From: simonmar@microsoft.com Date: Fri, 14 Dec 2007 13:58:42 +0000 (+0000) Subject: calculate wastage due to unused memory at the end of each block X-Git-Tag: Before_cabalised-GHC~270 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=2cf1115cd06678e5255c39e9fd56787031c31c06;p=ghc-hetmet.git calculate wastage due to unused memory at the end of each block --- diff --git a/includes/Storage.h b/includes/Storage.h index a40fd95..62d57b1 100644 --- a/includes/Storage.h +++ b/includes/Storage.h @@ -519,7 +519,9 @@ extern void GetRoots ( evac_fn evac ); extern ullong RTS_VAR(total_allocated); extern lnat calcAllocated ( void ); -extern lnat calcLive ( void ); +extern lnat calcLiveBlocks ( void ); +extern lnat calcLiveWords ( void ); +extern lnat countOccupied ( bdescr *bd ); extern lnat calcNeeded ( void ); #if defined(DEBUG) diff --git a/rts/Stats.c b/rts/Stats.c index 7059feb..b9df019 100644 --- a/rts/Stats.c +++ b/rts/Stats.c @@ -676,14 +676,10 @@ statDescribeGens(void) for (bd = step->large_objects, lge = 0; bd; bd = bd->link) { lge++; } - live = step->n_large_blocks * BLOCK_SIZE; - bd = step->blocks; // This live figure will be slightly less that the "live" figure // given by +RTS -Sstderr, because we take don't count the // slop at the end of each block. - for (; bd; bd = bd->link) { - live += (bd->free - bd->start) * sizeof(W_); - } + live += countOccupied(step->blocks) + countOccupied(step->large_objects); if (s != 0) { debugBelch("%36s",""); } diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 244da13..49f9831 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -580,7 +580,9 @@ GarbageCollect ( rtsBool force_major_gc ) resize_generations(); // Guess the amount of live data for stats. - live = calcLive(); + live = calcLiveBlocks() * BLOCK_SIZE_W; + debugTrace(DEBUG_gc, "Slop: %ldKB", + (live - calcLiveWords()) / (1024/sizeof(W_))); // Free the small objects allocated via allocate(), since this will // all have been copied into G0S1 now. diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index c441826..ecd9b54 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -918,15 +918,15 @@ calcAllocated( void ) /* Approximate the amount of live data in the heap. To be called just * after garbage collection (see GarbageCollect()). */ -extern lnat -calcLive(void) +lnat +calcLiveBlocks(void) { nat g, s; lnat live = 0; step *stp; if (RtsFlags.GcFlags.generations == 1) { - return (g0s0->n_large_blocks + g0s0->n_blocks) * BLOCK_SIZE_W; + return g0s0->n_large_blocks + g0s0->n_blocks; } for (g = 0; g < RtsFlags.GcFlags.generations; g++) { @@ -938,12 +938,50 @@ calcLive(void) continue; } stp = &generations[g].steps[s]; - live += (stp->n_large_blocks + stp->n_blocks) * BLOCK_SIZE_W; + live += stp->n_large_blocks + stp->n_blocks; } } return live; } +lnat +countOccupied(bdescr *bd) +{ + lnat words; + + words = 0; + for (; bd != NULL; bd = bd->link) { + words += bd->free - bd->start; + } + return words; +} + +lnat +calcLiveWords(void) +{ + nat g, s; + lnat live; + step *stp; + + if (RtsFlags.GcFlags.generations == 1) { + return countOccupied(g0s0->blocks) + countOccupied(g0s0->large_objects); + } + + live = 0; + for (g = 0; g < RtsFlags.GcFlags.generations; g++) { + for (s = 0; s < generations[g].n_steps; s++) { + /* approximate amount of live data (doesn't take into account slop + * at end of each block). + */ + if (g == 0 && s == 0) continue; + stp = &generations[g].steps[s]; + live += countOccupied(stp->blocks) + + countOccupied(stp->large_objects); + } + } + return live; +} + /* Approximate the number of blocks that will be needed at the next * garbage collection. *