summaryrefslogtreecommitdiff
blob: dc5410da30207bde84c771ca388d79b87059f633 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
commit 501e05bb1b8974fc8b6c9eee86c87c367e87a211
Author: Sergei Trofimovich <slyfox@gentoo.org>
Date:   Tue Aug 30 12:10:47 2016 +0100

    GhcMake: limit Capability count to CPU count in parallel mode
    
    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

diff --git a/compiler/main/GhcMake.hs b/compiler/main/GhcMake.hs
index 9dc43cd..905df63 100644
--- a/compiler/main/GhcMake.hs
+++ b/compiler/main/GhcMake.hs
@@ -761,7 +761,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