我偶然發現了一個存在於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只是一個例子,我不想用一些精心設計的計算來複雜化示例代碼。 –