【发布时间】:2011-07-17 18:55:11
【问题描述】:
我刚刚说过要在 GHC 6.12 中使用 haskell 半显式并行性。我编写了以下 haskell 代码来并行计算 fibonnaci 函数在列表中 4 个元素上的映射,同时计算 sumEuler 函数在两个元素上的映射。
import Control.Parallel
import Control.Parallel.Strategies
fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
mkList :: Int -> [Int]
mkList n = [1..n-1]
relprime :: Int -> Int -> Bool
relprime x y = gcd x y == 1
euler :: Int -> Int
euler n = length (filter (relprime n) (mkList n))
sumEuler :: Int -> Int
sumEuler = sum . (map euler) . mkList
-- parallel initiation of list walk
mapFib :: [Int]
mapFib = map fib [37, 38, 39, 40]
mapEuler :: [Int]
mapEuler = map sumEuler [7600, 7600]
parMapFibEuler :: Int
parMapFibEuler = (forceList mapFib) `par` (forceList mapEuler `pseq` (sum mapFib + sum mapEuler))
-- how to evaluate in whnf form by forcing
forceList :: [a] -> ()
forceList [] = ()
forceList (x:xs) = x `pseq` (forceList xs)
main = do putStrLn (" sum : " ++ show parMapFibEuler)
为了并行改进我的程序,我用 par 和 pseq 以及一个 forcing 函数来强制执行 whnf 评估。我的问题是,通过查看线程范围,我似乎没有获得任何并行性。情况更糟,因为我没有获得任何加速。
这就是为什么我有这两个问题
问题 1如何修改我的代码以利用任何并行性?
问题 2 如何编写程序以使用 Strategies(parMap、parList、rdeepseq 等...)?
策略的首次改进
根据他的贡献
parMapFibEuler = (mapFib, mapEuler) `using` s `seq` (sum mapFib + sum mapEuler) where
s = parTuple2 (seqList rseq) (seqList rseq)
并行性出现在线程范围中,但不足以显着加速
【问题讨论】:
-
并行包在GHC 7中有很大的改进,你也可以考虑升级一下。
-
你可以记住你的 fib 函数以获得一些加速...
标签: haskell parallel-processing multicore