diff options
author | Simon Marlow <marlowsd@gmail.com> | 2016-04-09 20:45:50 +0100 |
---|---|---|
committer | Simon Marlow <smarlow@fb.com> | 2016-05-04 05:30:30 -0700 |
commit | 76ee260778991367b8dbf07ecf7afd31f826c824 (patch) | |
tree | fbddddf878413dab3c01abf8108c26d2bd20db4c /rts/RtsFlags.c | |
parent | f9d93751126e58fb990335095e02fd81a3595fde (diff) | |
download | haskell-76ee260778991367b8dbf07ecf7afd31f826c824.tar.gz |
Allow limiting the number of GC threads (+RTS -qn<n>)
This allows the GC to use fewer threads than the number of capabilities.
At each GC, we choose some of the capabilities to be "idle", which means
that the thread running on that capability (if any) will sleep for the
duration of the GC, and the other threads will do its work. We choose
capabilities that are already idle (if any) to be the idle capabilities.
The idea is that this helps in the following situation:
* We want to use a large -N value so as to make use of hyperthreaded
cores
* We use a large heap size, so GC is infrequent
* But we don't want to use all -N threads in the GC, because that
thrashes the memory too much.
See docs for usage.
Diffstat (limited to 'rts/RtsFlags.c')
-rw-r--r-- | rts/RtsFlags.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index bffb1287e5..73c5b4564a 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -226,6 +226,7 @@ void initRtsFlagsDefaults(void) RtsFlags.ParFlags.parGcLoadBalancingEnabled = rtsTrue; RtsFlags.ParFlags.parGcLoadBalancingGen = 1; RtsFlags.ParFlags.parGcNoSyncWithIdle = 0; + RtsFlags.ParFlags.parGcThreads = 0; /* defaults to -N */ RtsFlags.ParFlags.setAffinity = 0; #endif @@ -388,6 +389,7 @@ usage_text[] = { " (default: 0, -qg alone turns off parallel GC)", " -qb[<n>] Use load-balancing in the parallel GC only for generations >= <n>", " (default: 1, -qb alone turns off load-balancing)", +" -qn<n> Use <n> threads for parallel GC (defaults to value of -N)", " -qa Use the OS to set thread affinity (experimental)", " -qm Don't automatically migrate threads between CPUs", " -qi<n> If a processor has been idle for the last <n> GCs, do not", @@ -1130,6 +1132,17 @@ error = rtsTrue; RtsFlags.ParFlags.parGcNoSyncWithIdle = strtol(rts_argv[arg]+3, (char **) NULL, 10); break; + case 'n': { + int threads; + threads = strtol(rts_argv[arg]+3, (char **) NULL, 10); + if (threads <= 0) { + errorBelch("-qn must be 1 or greater"); + error = rtsTrue; + } else { + RtsFlags.ParFlags.parGcThreads = threads; + } + break; + } case 'a': RtsFlags.ParFlags.setAffinity = rtsTrue; break; @@ -1370,6 +1383,13 @@ static void normaliseRtsOpts (void) "of the stack chunk size (-kc)"); errorUsage(); } + +#ifdef THREADED_RTS + if (RtsFlags.ParFlags.parGcThreads > RtsFlags.ParFlags.nNodes) { + errorBelch("GC threads (-qn) must be between 1 and the value of -N"); + errorUsage(); + } +#endif } static void errorUsage (void) |