Parallelism
The Par monad (monad-par) offers deterministic parallelism with explicit dataflow. massiv and accelerate (GPU) provide data-parallel arrays. Repa is older.
Parallelism is deterministic in pure code: the result is the same regardless of scheduling.
-- Pure parallelism: evaluation strategies (parallel package)
import Control.Parallel.Strategies
fib :: Int -> Integer
fib n = if n < 2 then toInteger n else fib (n - 1) + fib (n - 2)
main :: IO ()
main = do
let results = map fib [25 .. 35] `using` parList rdeepseq -- evaluate list elements in parallel
print (sum results)
let (a, b) = runEval $ do
x <- rpar (fib 33) -- spark in parallel
y <- rseq (fib 32) -- evaluate now
_ <- rseq x
pure (x, y)
print (a + b)
print (sum (parMap rdeepseq fib [20 .. 30]))ghc -O2 -threaded -rtsopts Main.hs
./Main +RTS -N4 -s # use 4 cores; -s prints GC and spark statistics
threadscope Main.eventlog # visualize parallel execution (compile with -eventlog, run with +RTS -l)