calculate and report slop (wasted space at the end of blocks)
authorSimon Marlow <simonmarhaskell@gmail.com>
Wed, 16 Apr 2008 22:15:16 +0000 (22:15 +0000)
committerSimon Marlow <simonmarhaskell@gmail.com>
Wed, 16 Apr 2008 22:15:16 +0000 (22:15 +0000)
rts/RtsStartup.c
rts/Stats.c
rts/Stats.h
rts/sm/GC.c

index 070275b..c55fdfb 100644 (file)
@@ -140,17 +140,20 @@ hs_init(int *argc, char **argv[])
        return;
     }
 
-#if defined(DEBUG)
-    /* Start off by initialising the allocator debugging so we can
-     * use it anywhere */
-    initAllocator();
-#endif
+    /* Initialise the stats department, phase 0 */
+    initStats0();
 
     /* Next we do is grab the start time...just in case we're
      * collecting timing statistics.
      */
     stat_startInit();
 
+#if defined(DEBUG)
+    /* Start off by initialising the allocator debugging so we can
+     * use it anywhere */
+    initAllocator();
+#endif
+
 #ifdef PAR
     /*
      * The parallel system needs to be initialised and synchronised before
@@ -181,6 +184,9 @@ hs_init(int *argc, char **argv[])
        setProgArgv(*argc,*argv);
     }
 
+    /* Initialise the stats department, phase 1 */
+    initStats1();
+
 #ifdef USE_PAPI
     papi_init();
 #endif
@@ -235,9 +241,6 @@ hs_init(int *argc, char **argv[])
     initTimer();
     startTimer();
 
-    /* Initialise the stats department */
-    initStats();
-
 #if defined(RTS_USER_SIGNALS)
     if (RtsFlags.MiscFlags.install_signal_handlers) {
         /* Initialise the user signal handler set */
index 461dabd..e331462 100644 (file)
@@ -68,6 +68,7 @@ static Ticks HCe_start_time, HCe_tot_time = 0;   // heap census prof elap time
 static lnat MaxResidency = 0;     // in words; for stats only
 static lnat AvgResidency = 0;
 static lnat ResidencySamples = 0; // for stats only
+static lnat MaxSlop = 0;
 
 static lnat GC_start_faults = 0, GC_end_faults = 0;
 
@@ -132,8 +133,56 @@ mut_user_time_during_heap_census( void )
 }
 #endif /* PROFILING */
 
+// initStats0() has no dependencies, it can be called right at the beginning
 void
-initStats(void)
+initStats0(void)
+{
+    ElapsedTimeStart = 0;
+
+    InitUserTime     = 0;
+    InitElapsedTime  = 0;
+    InitElapsedStamp = 0;
+
+    MutUserTime      = 0;
+    MutElapsedTime   = 0;
+    MutElapsedStamp  = 0;
+
+    ExitUserTime     = 0;
+    ExitElapsedTime  = 0;
+
+    GC_tot_alloc     = 0;
+    GC_tot_copied    = 0;
+    GC_par_max_copied = 0;
+    GC_par_avg_copied = 0;
+    GC_start_time = 0;
+    GC_tot_time  = 0;
+    GCe_start_time = 0;
+    GCe_tot_time = 0;
+
+#ifdef PROFILING
+    RP_start_time  = 0;
+    RP_tot_time  = 0;
+    RPe_start_time = 0;
+    RPe_tot_time = 0;
+
+    HC_start_time = 0;
+    HC_tot_time = 0;
+    HCe_start_time = 0;
+    HCe_tot_time = 0;
+#endif
+
+    MaxResidency = 0;
+    AvgResidency = 0;
+    ResidencySamples = 0;
+    MaxSlop = 0;
+
+    GC_start_faults = 0;
+    GC_end_faults = 0;
+}    
+
+// initStats1() can be called after setupRtsFlags()
+void
+initStats1 (void)
 {
     nat i;
   
@@ -153,7 +202,7 @@ initStats(void)
        GC_coll_times[i] = 0;
        GC_coll_etimes[i] = 0;
     }
-}    
+}
 
 /* -----------------------------------------------------------------------------
    Initialisation time...
@@ -298,7 +347,7 @@ stat_startGC(void)
 
 void
 stat_endGC (lnat alloc, lnat live, lnat copied, lnat gen,
-            lnat max_copied, lnat avg_copied)
+            lnat max_copied, lnat avg_copied, lnat slop)
 {
     if (RtsFlags.GcFlags.giveStats != NO_GC_STATS) {
        Ticks time, etime, gc_time, gc_etime;
@@ -353,6 +402,8 @@ stat_endGC (lnat alloc, lnat live, lnat copied, lnat gen,
            ResidencySamples++;
            AvgResidency += live;
        }
+
+        if (slop > MaxSlop) MaxSlop = slop;
     }
 
     if (rub_bell) {
@@ -545,6 +596,10 @@ stat_exit(int alloc)
                statsPrintf("%16s bytes maximum residency (%ld sample(s))\n",
                        temp, ResidencySamples);
            }
+
+           ullong_format_string(MaxSlop*sizeof(W_), temp, rtsTrue/*commas*/);
+           statsPrintf("%16s bytes maximum slop\n", temp);
+
            statsPrintf("%16ld MB total memory in use\n\n", 
                    mblocks_allocated * MBLOCK_SIZE / (1024 * 1024));
 
index 12311ee..bd39ced 100644 (file)
@@ -17,7 +17,7 @@ void      stat_endInit(void);
 void      stat_startGC(void);
 void      stat_endGC (lnat alloc, lnat live, 
                      lnat copied, lnat gen,
-                      lnat max_copied, lnat avg_copied);
+                      lnat max_copied, lnat avg_copied, lnat slop);
 
 #ifdef PROFILING
 void      stat_startRP(void);
@@ -39,7 +39,8 @@ void      stat_endExit(void);
 void      stat_exit(int alloc);
 void      stat_workerStop(void);
 
-void      initStats(void);
+void      initStats0(void);
+void      initStats1(void);
 
 double    mut_user_time_during_GC(void);
 double    mut_user_time(void);
index 97b32b6..7a6889c 100644 (file)
@@ -181,7 +181,7 @@ GarbageCollect ( rtsBool force_major_gc )
 {
   bdescr *bd;
   step *stp;
-  lnat live, allocated, max_copied, avg_copied;
+  lnat live, allocated, max_copied, avg_copied, slop;
   lnat oldgen_saved_blocks = 0;
   gc_thread *saved_gct;
   nat g, s, t, n;
@@ -722,7 +722,8 @@ GarbageCollect ( rtsBool force_major_gc )
 #endif
 
   // ok, GC over: tell the stats department what happened. 
-  stat_endGC(allocated, live, copied, N, max_copied, avg_copied);
+  slop = calcLiveBlocks() * BLOCK_SIZE_W - live;
+  stat_endGC(allocated, live, copied, N, max_copied, avg_copied, slop);
 
 #if defined(RTS_USER_SIGNALS)
   if (RtsFlags.MiscFlags.install_signal_handlers) {