From ffb8e8f86d5162d7c225d810d70403b8698624ee Mon Sep 17 00:00:00 2001 From: Jesse McDonald Date: Sat, 10 Apr 2010 22:49:44 -0500 Subject: [PATCH] Separate statistics for Gen-0 vs. Gen-1 garbage collection. --- gc.c | 87 ++++++++++++++++++++++++++++++++++++------------------------ gc.h | 14 +++++----- 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/gc.c b/gc.c index c64c3e0..addb35d 100644 --- a/gc.c +++ b/gc.c @@ -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) { - gc_stats.gen0_passes = 0; - gc_stats.gen1_passes = 0; - gc_stats.total_ns = 0; - gc_stats.total_freed = 0; - gc_stats.high_water = 0; - gc_stats.max_ns = 0; + int i; + + for (i = 0; i < 2; ++i) + { + gc_stats.gen[i].passes = 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 @@ -569,16 +574,16 @@ static void collect_gen0_garbage(void) nsec = (end_time.tv_sec - start_time.tv_sec) * 1000000000LL; 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) - gc_stats.max_ns = nsec; + if (nsec > gc_stats.gen[0].max_ns) + gc_stats.gen[0].max_ns = nsec; } #endif - gc_stats.total_freed -= initial_free_space; - gc_stats.total_freed += gc_gen0_free_space(); - gc_stats.total_freed += gc_gen1_free_space(); - ++gc_stats.gen0_passes; + gc_stats.gen[0].total_freed -= initial_free_space; + gc_stats.gen[0].total_freed += gc_gen0_free_space(); + gc_stats.gen[0].total_freed += gc_gen1_free_space(); + ++gc_stats.gen[0].passes; #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; #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 } @@ -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_nsec - start_time.tv_nsec); - gc_stats.total_ns += nsec; + gc_stats.gen[1].total_ns += nsec; - if (nsec > gc_stats.max_ns) - gc_stats.max_ns = nsec; + if (nsec > gc_stats.gen[1].max_ns) + gc_stats.gen[1].max_ns = nsec; } #endif - gc_stats.total_freed -= initial_free_space; - gc_stats.total_freed += gc_gen0_free_space(); - gc_stats.total_freed += gc_gen1_free_space(); - ++gc_stats.gen1_passes; + gc_stats.gen[1].total_freed -= initial_free_space; + gc_stats.gen[1].total_freed += gc_gen0_free_space(); + gc_stats.gen[1].total_freed += gc_gen1_free_space(); + ++gc_stats.gen[1].passes; #endif } @@ -1429,25 +1434,37 @@ void fprint_value(FILE *f, value_t v) _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) { - 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 double max_time = gc_stats.max_ns / 1.0e9; + const llsize_t total_freed = gc_stats.gen[0].total_freed + gc_stats.gen[1].total_freed; + 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", - gc_stats.total_freed, - gc_stats.gen0_passes, - gc_stats.gen1_passes, - total_time, - (gc_stats.total_freed / total_time) / (1024*1024)); + fprintf(f, "GC: %lld bytes freed by %d GCs in %0.6f sec => %0.3f MB/sec.\n", + total_freed, + gc_stats.gen[0].passes + gc_stats.gen[1].passes, + ns2sec(total_ns), + (total_freed / ns2sec(total_ns)) / (1024*1024)); - fprintf(f, "GC: Avg. time was %0.6f sec, max %0.6f.\n", - (total_time / (gc_stats.gen0_passes + gc_stats.gen1_passes)), max_time); + fprintf(f, "GC: %d Gen-0 passes; avg. time was %0.6f sec, max %0.6f.\n", + 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", - gc_stats.high_water, gc_gen1_max_size); + fprintf(f, "GC: %d Gen-1 passes; avg. time was %0.6f sec, max %0.6f.\n", + 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 { diff --git a/gc.h b/gc.h index 4b61ae9..e35c4f6 100644 --- a/gc.h +++ b/gc.h @@ -168,12 +168,14 @@ typedef unsigned long long llsize_t; typedef struct gc_stats { - int gen0_passes; - int gen1_passes; - nsec_t total_ns; - llsize_t total_freed; - size_t high_water; - nsec_t max_ns; + struct { + int passes; + nsec_t total_ns; + nsec_t max_ns; + nsec_t max_gen1_ns; + llsize_t total_freed; + } gen[2]; + size_t gen1_high_water; } gc_stats_t; extern gc_stats_t gc_stats;