我偶然发现了一个存在于Haskell中的Eval
monad和rpar
Strategy
的问题。请考虑下面的代码:如何在Haskell中使用rpar策略并行评估元组?
module Main where
import Control.Parallel.Strategies
main :: IO()
main = print . sum . inParallel2 $ [1..10000]
inParallel :: [Double] -> [Double]
inParallel xss = runEval . go $ xss
where
go [] = return []
go (x:xs) = do
x' <- rpar $ x + 1
xs' <- go xs
return (x':xs')
inParallel2 :: [Double] -> [Double]
inParallel2 xss = runEval . go $ xss
where
go [] = return []
go [x] = return $ [x + 1]
go (x:y:xs) = do
(x',y') <- rpar $ (x + 1, y + 1)
xs' <- go xs
return (x':y':xs'
我编译,这样运行:
ghc -O2 -Wall -threaded -rtsopts -fforce-recomp -eventlog eval.hs
./eval +RTS -N3 -ls -s
当我使用inParallel
功能并行工作正常。在运行时输出统计资料中看到:
SPARKS: 100000 (100000 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
当我切换到inParallel2
功能所有的并行机制消失了:
SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
为什么没有并行元组工作的评价是什么?我试图强制元组之前传递给rpar:
rpar $!! (x + 1, y + 1)
但仍然没有结果。我究竟做错了什么?
谢谢!当我阅读Marlow的教程并做一些自己的练习时,实际上出现了这个问题。加1只是一个例子,我不想用一些精心设计的计算来复杂化示例代码。 –