Separate statistics for Gen-0 vs. Gen-1 garbage collection.

This commit is contained in:
Jesse D. McDonald 2010-04-10 22:49:44 -05:00
parent 0a6d2f3f73
commit ffb8e8f86d
2 changed files with 60 additions and 41 deletions

87
gc.c
View File

@ -403,12 +403,17 @@ void gc_init(size_t gen0_size, size_t gen1_min_size, size_t gen1_max_size)
void clear_gc_stats(void) void clear_gc_stats(void)
{ {
gc_stats.gen0_passes = 0; int i;
gc_stats.gen1_passes = 0;
gc_stats.total_ns = 0; for (i = 0; i < 2; ++i)
gc_stats.total_freed = 0; {
gc_stats.high_water = 0; gc_stats.gen[i].passes = 0;
gc_stats.max_ns = 0; gc_stats.gen[i].total_ns = 0;
gc_stats.gen[i].max_ns = 0;
gc_stats.gen[i].total_freed = 0;
}
gc_stats.gen1_high_water = 0;
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -569,16 +574,16 @@ static void collect_gen0_garbage(void)
nsec = (end_time.tv_sec - start_time.tv_sec) * 1000000000LL; nsec = (end_time.tv_sec - start_time.tv_sec) * 1000000000LL;
nsec += (end_time.tv_nsec - start_time.tv_nsec); nsec += (end_time.tv_nsec - start_time.tv_nsec);
gc_stats.total_ns += nsec; gc_stats.gen[0].total_ns += nsec;
if (nsec > gc_stats.max_ns) if (nsec > gc_stats.gen[0].max_ns)
gc_stats.max_ns = nsec; gc_stats.gen[0].max_ns = nsec;
} }
#endif #endif
gc_stats.total_freed -= initial_free_space; gc_stats.gen[0].total_freed -= initial_free_space;
gc_stats.total_freed += gc_gen0_free_space(); gc_stats.gen[0].total_freed += gc_gen0_free_space();
gc_stats.total_freed += gc_gen1_free_space(); gc_stats.gen[0].total_freed += gc_gen1_free_space();
++gc_stats.gen0_passes; ++gc_stats.gen[0].passes;
#endif #endif
} }
@ -1027,9 +1032,9 @@ static void update_soft_limit(size_t min_free)
gc_gen1_range_end = gc_gen1_ranges[gc_gen1_current_range] + gc_gen1_soft_limit; gc_gen1_range_end = gc_gen1_ranges[gc_gen1_current_range] + gc_gen1_soft_limit;
#ifndef NO_STATS #ifndef NO_STATS
if (gc_gen1_soft_limit > gc_stats.high_water) if (gc_gen1_soft_limit > gc_stats.gen1_high_water)
{ {
gc_stats.high_water = gc_gen1_soft_limit; gc_stats.gen1_high_water = gc_gen1_soft_limit;
} }
#endif #endif
} }
@ -1153,16 +1158,16 @@ static void collect_gen1_garbage(size_t min_free)
nsec = (end_time.tv_sec - start_time.tv_sec) * 1000000000LL; nsec = (end_time.tv_sec - start_time.tv_sec) * 1000000000LL;
nsec += (end_time.tv_nsec - start_time.tv_nsec); nsec += (end_time.tv_nsec - start_time.tv_nsec);
gc_stats.total_ns += nsec; gc_stats.gen[1].total_ns += nsec;
if (nsec > gc_stats.max_ns) if (nsec > gc_stats.gen[1].max_ns)
gc_stats.max_ns = nsec; gc_stats.gen[1].max_ns = nsec;
} }
#endif #endif
gc_stats.total_freed -= initial_free_space; gc_stats.gen[1].total_freed -= initial_free_space;
gc_stats.total_freed += gc_gen0_free_space(); gc_stats.gen[1].total_freed += gc_gen0_free_space();
gc_stats.total_freed += gc_gen1_free_space(); gc_stats.gen[1].total_freed += gc_gen1_free_space();
++gc_stats.gen1_passes; ++gc_stats.gen[1].passes;
#endif #endif
} }
@ -1429,25 +1434,37 @@ void fprint_value(FILE *f, value_t v)
_fprint_value(f, v, NULL); _fprint_value(f, v, NULL);
} }
static double ns2sec(nsec_t ns) __attribute__ ((const));
static double ns2sec(nsec_t ns)
{
return ns / 1.0e9;
}
void fprint_gc_stats(FILE *f) void fprint_gc_stats(FILE *f)
{ {
if ((gc_stats.gen0_passes + gc_stats.gen1_passes) > 0) if (gc_stats.gen[0].passes || gc_stats.gen[1].passes)
{ {
const double total_time = gc_stats.total_ns / 1.0e9; const llsize_t total_freed = gc_stats.gen[0].total_freed + gc_stats.gen[1].total_freed;
const double max_time = gc_stats.max_ns / 1.0e9; const nsec_t total_ns = gc_stats.gen[0].total_ns + gc_stats.gen[1].total_ns;
fprintf(f, "GC: %lld bytes freed by %d+%d GCs in %0.6f sec => %0.3f MB/sec.\n", fprintf(f, "GC: %lld bytes freed by %d GCs in %0.6f sec => %0.3f MB/sec.\n",
gc_stats.total_freed, total_freed,
gc_stats.gen0_passes, gc_stats.gen[0].passes + gc_stats.gen[1].passes,
gc_stats.gen1_passes, ns2sec(total_ns),
total_time, (total_freed / ns2sec(total_ns)) / (1024*1024));
(gc_stats.total_freed / total_time) / (1024*1024));
fprintf(f, "GC: Avg. time was %0.6f sec, max %0.6f.\n", fprintf(f, "GC: %d Gen-0 passes; avg. time was %0.6f sec, max %0.6f.\n",
(total_time / (gc_stats.gen0_passes + gc_stats.gen1_passes)), max_time); gc_stats.gen[0].passes,
ns2sec(gc_stats.gen[0].total_ns) / gc_stats.gen[0].passes,
ns2sec(gc_stats.gen[0].max_ns));
fprintf(f, "GC: The soft-limit peaked at %d bytes out of %d allocated.\n", fprintf(f, "GC: %d Gen-1 passes; avg. time was %0.6f sec, max %0.6f.\n",
gc_stats.high_water, gc_gen1_max_size); gc_stats.gen[1].passes,
ns2sec(gc_stats.gen[1].total_ns) / gc_stats.gen[1].passes,
ns2sec(gc_stats.gen[1].max_ns));
fprintf(f, "GC: The Gen-1 soft-limit peaked at %d bytes out of %d allocated.\n",
gc_stats.gen1_high_water, gc_gen1_max_size);
} }
else else
{ {

14
gc.h
View File

@ -168,12 +168,14 @@ typedef unsigned long long llsize_t;
typedef struct gc_stats typedef struct gc_stats
{ {
int gen0_passes; struct {
int gen1_passes; int passes;
nsec_t total_ns; nsec_t total_ns;
llsize_t total_freed; nsec_t max_ns;
size_t high_water; nsec_t max_gen1_ns;
nsec_t max_ns; llsize_t total_freed;
} gen[2];
size_t gen1_high_water;
} gc_stats_t; } gc_stats_t;
extern gc_stats_t gc_stats; extern gc_stats_t gc_stats;