parTraversable没有产生任何火花

时间:2017-10-06 20:18:56

标签: haskell parallel-processing

当我使用-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

我错过了什么?

1 个答案:

答案 0 :(得分:5)

我可以重现你的行为(ghc-8.2.1,parallel-3.2.1.1)。

稍后,Strategies.hsRULES个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
 #-}