From: Simon Marlow Date: Mon, 30 Nov 2009 15:18:36 +0000 (+0000) Subject: Implement a new heap-tuning option: -H X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=323950933d3260503186b93e7a5a7bdaa4822c1b Implement a new heap-tuning option: -H -H alone causes the RTS to use a larger nursery, but without exceeding the amount of memory that the application is already using. It trades off GC time against locality: the default setting is to use a fixed-size 512k nursery, but this is sometimes worse than using a very large nursery despite the worse locality. Not all programs get faster, but some programs that use large heaps do much better with -H. e.g. this helps a lot with #3061 (binary-trees), though not as much as specifying -H. Typically using -H is better than plain -H, because the runtime doesn't know ahead of time how much memory you want to use. Should -H be on by default? I'm not sure, it makes some programs go slower, but others go faster. --- diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h index e78bed2..b861461 100644 --- a/includes/rts/Flags.h +++ b/includes/rts/Flags.h @@ -34,6 +34,7 @@ struct GC_FLAGS { nat minAllocAreaSize; /* in *blocks* */ nat minOldGenSize; /* in *blocks* */ nat heapSizeSuggestion; /* in *blocks* */ + rtsBool heapSizeSuggestionAuto; double oldGenFactor; double pcFreeHeap; diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index a6dbaf0..a646e57 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -70,6 +70,7 @@ void initRtsFlagsDefaults(void) RtsFlags.GcFlags.minOldGenSize = (1024 * 1024) / BLOCK_SIZE; RtsFlags.GcFlags.maxHeapSize = 0; /* off by default */ RtsFlags.GcFlags.heapSizeSuggestion = 0; /* none */ + RtsFlags.GcFlags.heapSizeSuggestionAuto = rtsFalse; RtsFlags.GcFlags.pcFreeHeap = 3; /* 3% */ RtsFlags.GcFlags.oldGenFactor = 2; RtsFlags.GcFlags.generations = 2; @@ -690,9 +691,13 @@ error = rtsTrue; break; case 'H': - RtsFlags.GcFlags.heapSizeSuggestion = - (nat)(decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX) / BLOCK_SIZE); - break; + if (rts_argv[arg][2] == '\0') { + RtsFlags.GcFlags.heapSizeSuggestionAuto = rtsTrue; + } else { + RtsFlags.GcFlags.heapSizeSuggestion = + (nat)(decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX) / BLOCK_SIZE); + } + break; #ifdef RTS_GTK_FRONTPANEL case 'f': diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 5097483..0593bd7 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -1548,6 +1548,10 @@ resize_generations (void) size = stg_max(live * RtsFlags.GcFlags.oldGenFactor, RtsFlags.GcFlags.minOldGenSize); + if (RtsFlags.GcFlags.heapSizeSuggestionAuto) { + RtsFlags.GcFlags.heapSizeSuggestion = size; + } + // minimum size for generation zero min_alloc = stg_max((RtsFlags.GcFlags.pcFreeHeap * max) / 200, RtsFlags.GcFlags.minAllocAreaSize);