当我使用-s
:
module Main where
import Control.Parallel.Strategies
main :: IO ()
main = do let xs = take 1000 $ product . take 1000 . repeat <$> [1..]
x = product (xs `using` parList rseq)
putStrLn (show x)
创建了Spark:
SPARKS:1000(993转换,0溢出,0哑,6 GC&#39; d,1失败)
如果我将parList
更改为parTraversable
x = product (xs `using` parTraversable rseq)
没有创建火花:
SPARKS:0(0转换,0溢出,0哑,0 GC&#39; d,0失败)
如果我将rseq
更改为rdeepseq
:
main = do let xs = (take 1000 $ product . take 1000 . repeat <$> [1..]) :: [Integer]
x = product (xs `using` parList rdeepseq)
putStrLn (show x)
没有产生火花
SPARKS:0(0转换,0溢出,0哑,0 GC&#39; d,0失败)
我使用的是parallel-3.2.1.1,在源代码中,parList
是使用parTraversable
定义的!
parList :: Strategy a -> Strategy [a]
parList = parTraversable
我错过了什么?
答案 0 :(得分:5)
我可以重现你的行为(ghc-8.2.1,parallel-3.2.1.1)。
稍后,Strategies.hs
是RULES
个pragma特殊情况parList rseq
。我想这是一个错误,它与parTraversable
有不同的行为(我不太了解内部情况,以确定错误所在的位置)。我建议您在parallel
问题跟踪器上提交一张票:https://github.com/haskell/parallel/issues
以下是相关代码,从文件的第505行开始:
-- Non-compositional version of 'parList', evaluating list elements
-- to weak head normal form.
-- Not to be exported; used for optimisation.
-- | DEPRECATED: use @'parList' 'rseq'@ instead
parListWHNF :: Strategy [a]
parListWHNF xs = go xs `pseq` return xs
where -- go :: [a] -> [a]
go [] = []
go (y:ys) = y `par` go ys
-- The non-compositional 'parListWHNF' might be more efficient than its
-- more compositional counterpart; use RULES to do the specialisation.
{-# NOINLINE [1] parList #-}
{-# NOINLINE [1] rseq #-}
{-# RULES
"parList/rseq" parList rseq = parListWHNF
#-}