X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fparallel.xml;h=37cafd2d764e2aad43ab3fa636099383f18a9ce8;hb=9a4ef343a46e823bcf949af8501c13cc8ca98fb1;hp=76d38dc6464031ed61928a6df316d172f81d5361;hpb=d5ab3b5e415ebdff8906dcac3451e7448d6bdb11;p=ghc-hetmet.git diff --git a/docs/users_guide/parallel.xml b/docs/users_guide/parallel.xml index 76d38dc..37cafd2 100644 --- a/docs/users_guide/parallel.xml +++ b/docs/users_guide/parallel.xml @@ -114,10 +114,10 @@ All these features are described in the papers mentioned earlier. infixr 0 `par` -infixr 1 `seq` +infixr 1 `pseq` -par :: a -> b -> b -seq :: a -> b -> b +par :: a -> b -> b +pseq :: a -> b -> b The expression (x `par` y) sparks the evaluation of x @@ -136,24 +136,35 @@ import Control.Parallel nfib :: Int -> Int nfib n | n <= 1 = 1 - | otherwise = par n1 (seq n2 (n1 + n2 + 1)) + | otherwise = par n1 (pseq n2 (n1 + n2 + 1)) where n1 = nfib (n-1) n2 = nfib (n-2) For values of n greater than 1, we use par to spark a thread to evaluate nfib (n-1), - and then we use seq to force the + and then we use pseq to force the parent thread to evaluate nfib (n-2) before going on to add together these two subexpressions. In this divide-and-conquer approach, we only spark a new thread for one branch of the computation (leaving the parent to evaluate the other branch). Also, we must use - seq to ensure that the parent will evaluate + pseq to ensure that the parent will evaluate n2 before n1 in the expression (n1 + n2 + 1). It is not sufficient to reorder the expression as (n2 + n1 + 1), because the compiler may not generate code to evaluate the addends from left to right. + + Note that we use pseq rather + than seq. The two are almost equivalent, but + differ in their runtime behaviour in a subtle + way: seq can evaluate its arguments in either + order, but pseq is required to evaluate its + first argument before its second, which makes it more suitable + for controlling the evaluation order in conjunction + with par. + + When using par, the general rule of thumb is that the sparked computation should be required at a later time, but not too soon. Also, the sparked computation should not be too small, otherwise @@ -161,6 +172,10 @@ nfib n | n <= 1 = 1 amount of parallelism gained. Getting these factors right is tricky in practice. + It is possible to glean a little information about how + well par is working from the runtime + statistics; see . + More sophisticated combinators for expressing parallelism are available from the Control.Parallel.Strategies module.