我有一個Conway的生命遊戲的實現。如果可能的話,我想通過使用並行性來加速它。Haskell parMap和並行性
life :: [(Int, Int)] -> [(Int, Int)]
life cells = map snd . filter rules . freq $ concatMap neighbours cells
where rules (n, c) = n == 3 || (n == 2 && c `elem` cells)
freq = map (length &&& head) . group . sort
parLife :: [(Int, Int)] -> [(Int, Int)]
parLife cells = parMap rseq snd . filter rules . freq . concat $ parMap rseq neighbours cells
where rules (n, c) = n == 3 || (n == 2 && c `elem` cells)
freq = map (length &&& head) . group . sort
neigbours :: (Int, Int) -> [(Int, Int)]
neighbours (x, y) = [(x + dx, y + dy) | dx <- [-1..1], dy <- [-1..1], dx /= 0 || dy /= 0]
在仿形
,鄰居佔所用的時間的6.3%,因此,雖然小我期望的noticable加速通過並聯映射它。
我用一個簡單的函數
main = print $ last $ take 200 $ iterate life fPent
where fPent = [(1, 2), (2, 2), (2, 1), (2, 3), (3, 3)]
測試和編譯的並行版本作爲
ghc --make -O2 -threaded life.hs
並運行它作爲
./life +RTS -N3
事實證明,並行版本是慢。我在這裏錯誤地使用parMap嗎?這是甚至可以使用並行性的情況嗎?
首先,你的計算機至少有3個內核?其次,並行性總是會帶來一些開銷,所以如果每個線程所做的工作都非常小,額外的開銷將超過任何加速。 – huon
我有一個i5-2500k,所以肯定有多達4個內核可用 – cdk
請注意,您可以從改進算法中獲得比並行化更大的加速。大部分時間都花在'sort'和'elem'上。使用單元格列表進行排序(並更改'fPent'以便對它進行排序)這一事實,可以大致減半時間。 –