Good day. Given code
import Control.DeepSeq
import Control.Exception
import Control.Parallel
import Control.Parallel.Strategies
import System.Environment
import Text.Printf
l = [34,56,43,1234,456,765,345,4574,58,878,978,456,34,234,1234123,1234,12341234]
f x = Just (sum [1..x])
fun1 :: [Maybe Integer]
fun1 = map f l `using` parList rdeepseq
fun2 :: [Maybe Integer]
fun2 = map f l `using` evalList (rparWith rdeepseq)
fun3 :: [Maybe Integer]
fun3 = map f l `using` evalList (rpar . force)
main :: IO ()
main = print fun1
Why fun1
and fun2
run sequentially?
From what I understood, rparWith should spark its argument. Answer here states the same. But for fun1 and fun2 I'm getting output like "SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)". So Sparks were not even created.
fun3
works as expected with sparks being created.
Ty for help
UPD: And I found that rdeepseq
makes example from book (Parallel and Concurrent Programming in Haskell) works in sequence. Book says:
And we can use parPair to write a Strategy that fully evaluates both components of a pair in parallel:
parPair rdeepseq rdeepseq :: (NFData a, NFData b) => Strategy (a,b)
To break down what happens when this Strategy is applied to a pair: parPair calls, and evalPair calls rparWith rdeepseq on each component of the pair. So the effect is that each component will be fully evaluated to normal form in parallel.
But if I run
(Just (fib 35), Just (fib 36)) `using` parPair rdeepseq rdeepseq
or even
(fib 35, fib 36) `using` parPair rdeepseq rdeepseq
Threadscope shows only one core running and 0 sparks created.
fib implemented like this (from book too)
fib :: Integer -> Integer
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)