EPS contention may be slowing down parallel make
Summary
I think it's likely that contention of the EPS is blocking parallel make from reaching its full potential on large shallow module graphs.
The EPS is stored in a global IORef and is regularly checked during typechecking. If an interface hasn't yet been loaded, then it will be loaded, typecheched (potentially loading further interfaces), and then atomically merged with the current value of the EPS.
From a quick glance at the code I'm seeing two potential issues:
-
Duplicated work due to two threads racing:
In a situation where two threads both discover that an interface is missing from the EPS, I think, they will duplicate work to load it.
-
Atomically updating the EPS blocks reads:
AFAIK using
atomicModifyIORef'
blocks reads, as it updates the IORef with a thunk that it then evaluates. While the thunk is under evaluation, other threads will be blocked if they try to look at it.
I say potential issues because I haven't done enough investigating to confirm if this is actually an issue. I'll try to do that in the next couple of weeks and come up with some strategies to mitigate it if it does turn out to be a problem.
Context
I was led to the EPS by looking at the DWARF decoded stacks of threads blocking on blackholes while compiling Cabal
.
Code that was looking things up in the EPS stood out to me. I used this branch of ghc https://gitlab.haskell.org/teo/ghc/-/commits/wip/blackhole-introspection