
#8972: Investigate adding fast compare-and-swap Int type/primops -------------------------------------+------------------------------------ Reporter: tibbe | Owner: tibbe Type: feature request | Status: new Priority: normal | Milestone: 7.10.1 Component: Compiler | Version: 7.9 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: #8157, #7883 -------------------------------------+------------------------------------ Comment (by nominolo): Replying to [comment:6 rrnewton]:
I suspect the problem with atomicModifyIORef's poor behavior may have to do with blackholes? Tracing ghc events will perturb these workloads a bunch I guess, but maybe threadscope could still tell us something wrt blackhole events.
We were affected by this issue and looked at the thread status of all threads and noticed that they all get blocked on a blackhole. We suspect there are two issues here: 1. Poor cache behaviour due to the CAS retry busy loop. 2. All the threads get queued up waiting for the thread that currently owns the blackhole to get scheduled again. The second point is a potential issue for many other applications (e.g,. if a thread is holding on to an MVar). In the operating system world they deal with those kinds of issues either using: - interrupt blocking: i.e., a thread cannot be de-scheduled while holding the lock - time-slice donation / priority boosting: If a thread enters a critical section and still has some alotted compute time left, it "donates" that time to the thread owning the critical section, so that it will make progress and leave the critical section. If you have thread priorities then you can temporarily raise the priority of the thread in the critical section. This rather complicated because priority boosting may have to be recursive (you have to boost to the priority of the highest-priority thread waiting), so not everyone likes this method. For GHC, I think it could be useful to have both mechanisms available. Marking a thread as non-interruptable could be exported from a "Here be dragons" module for using when you know that a thread will hold a lock/MVar only for a very short time. For thunks, when a thread blocks on a blackhole, the scheduler should probably then schedule that thread next. This way, the time spent evaluating a blackhole will be proportional to the number of threads waiting on it. I don't know if the reduced fairness causes issues here, though. You could mark a blackhole as "boosted" meaning, that as soon the blackhole is updated we not just wake up all threads in the run-queue, but also yield to the first thread in the blackhole. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8972#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler