GhcMake: limit Capability count to CPU count in parallel mode
authorSergei Trofimovich <slyfox@gentoo.org>
Tue, 30 Aug 2016 11:10:47 +0000 (12:10 +0100)
committerSergei Trofimovich <siarheit@google.com>
Tue, 30 Aug 2016 11:11:06 +0000 (12:11 +0100)
In Trac #9221 one of problems using high --jobs=<N>
is amount of mutator (or GC) threads we crate.

We use userspace spinning-and-yielding (see ACQUIRE_SPIN_LOCK)
to acess work stealing queues. In case of
N-worker-threads > N-CPUs fraction of time when
thread holding spin lock gets descheduled by kernel
increases. That causes other threads to waste CPU time
before giving up CPU.

Signed-off-by: Sergei Trofimovich <siarheit@google.com>
Test Plan:
ghc --make -j8 and -j80 have comparable sys time
on a 8-core system.

Reviewers: austin, gintas, bgamari, simonmar

Reviewed By: bgamari, simonmar

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2482

GHC Trac Issues: #9221

compiler/main/GhcMake.hs

index bb1c8e3..9197b2c 100644 (file)
@@ -762,7 +762,12 @@ parUpsweep n_jobs old_hpt stable_mods cleanup sccs = do
 
     let updNumCapabilities = liftIO $ do
             n_capabilities <- getNumCapabilities
-            unless (n_capabilities /= 1) $ setNumCapabilities n_jobs
+            n_cpus <- getNumProcessors
+            -- Setting number of capabilities more than
+            -- CPU count usually leads to high userspace
+            -- lock contention. Trac #9221
+            let n_caps = min n_jobs n_cpus
+            unless (n_capabilities /= 1) $ setNumCapabilities n_caps
             return n_capabilities
     -- Reset the number of capabilities once the upsweep ends.
     let resetNumCapabilities orig_n = liftIO $ setNumCapabilities orig_n