McGill
McGill

Reputation: 49

Why will the following run in parallel rather than sequentially?

Given the following functions for evalPair, parPair and deepSeq respectively,

evalPair :: Strategy a -> Strategy b -> Strategy (a,b)
evalPair sa sb (a,b) = do
      a' <- sa a
      b' <- sb b
      return (a',b')

parPair :: Strategy a -> Strategy b -> Strategy (a,b)
parPair sa sb = evalPair (rparWith sa) (rparWith sb)

rdeepseq :: NFData a => Strategy a
rdeepseq x = rseq (force x)

The question is why will the following code be evaluated in parallel as the author claims?

parPair rdeepseq rdeepseq :: (NFData a, NFData b) => Strategy (a,b)

I am in dount since Simon Marlow says the following

To break down what happens when this Strategy is applied to a pair: parPair calls evalPair, 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.

According to what I see rparWith rdeepseq is informally rpar . rseq . force which means the argument will be evaluated to normal form, which it will be evaluated with rseq sequentially, and hence in the end the rpar is of no use in a parallel context.

Everything is taken from Simon Marlow's book.


Thanks in advance.

Upvotes: 2

Views: 342

Answers (1)

Zeta
Zeta

Reputation: 105876

Let's have a look at parPair rdeepseq rdeepseq:

parPair rdeepseq rdeepseq (a,b)
 = evalPair (rparWith rdeepseq) (rparWith rdeepseq) (a,b)
 = do
    a' <- rparWith rdeepseq a
    b' <- rparWith rdeepseq b
    return (a', b')

Since rparWith sparks it arguments, rdeepseq a will be evaluated in parallel (possibly). It wouldn't be in parallel, if you were to use

evalPair rdeepseq rdeepseq

instead. The rparWith is essential, as it sparks its argument for evaluation with the given strategy.

Upvotes: 4

Related Questions