haskellparallel-processingspeculative-execution

Why do we need 'seq' or 'pseq' with 'par' in Haskell?


I'm trying to understand why we need all parts of the standard sample code:

a `par` b `pseq` a+b

Why won't the following be sufficient?

a `par` b `par` a+b

The above expression seems very descriptive: Try to evaluate both a and b in parallel, and return the result a+b. Is the reason only that of efficiency: the second version would spark off twice instead of once?

How about the following, more succinct version?

a `par` a+b

Why would we need to make sure b is evaluated before a+b as in the original, standard code?


Solution

  • Ok. I think the following paper answers my question: http://community.haskell.org/~simonmar/papers/threadscope.pdf

    In summary, the problem with

    a `par` b `par` a+b 
    

    and

    a `par` a+b
    

    is the lack of ordering of evaluation. In both versions, the main thread gets to work on a (or sometimes b) immediately, causing the sparks to "fizzle" away immediately since there is no more need to start a thread to evaluate what the main thread has already started evaluating.

    The original version

    a `par` b `pseq` a+b
    

    ensures the main thread works on b before a+b (or else would have started evaluating a instead), thus giving a chance for the spark a to materialize into a thread for parallel evaluation.