使用Control.Parallel使用Data.Map.StrictMap.Maps

时间:2016-06-14 07:06:37

标签: haskell dictionary parallel-processing

我有以下代码。 M前缀指定Data.Map.Strict中的函数,TableData.Map.Strict.Map Mapping Bool的类型别名,其中Mapping是任意不透明结构。

computeCoverage :: Table -> Expr -> Maybe Coverage 
computeCoverage t e = go t True M.empty
  where go src flag targ
          | null src = if flag
                       then Nothing
                       else Just (M.size t, targ)
          | otherwise = let ((m, b), rest) = M.deleteFindMin src 
                            result = interpret e m
                            flag' = result && flag in 
              go rest flag' (if b == result then targ else M.insert m b targ)

我希望能够使用Control.Parallel以尽可能多的并行性来执行此操作。但是,我不知道该怎么做。根据阅读Data.Map.Strict,您应该做的就是调用splitRoot,然后在结果列表中执行您想要的任何并行操作,然后重新组合(我猜?)。我基本上有正确的想法吗?如果没有,我应该怎么做才能并行化上面的代码?

1 个答案:

答案 0 :(得分:3)

这是一个人为的例子。您只需使用parMap而不是M.splitRoot m

import qualified Data.Map.Strict as M
import Control.Parallel.Strategies
import System.Environment

fib 0 = 0
fib 1 = 1
fib n = fib (n-2) + fib (n-1)

theMap :: Int -> M.Map Int Int
theMap n = M.fromList [ (x, 33 + mod x 3) | x <- [1..n] ]

isInteresting n = mod (fib n) 2 == 0

countInteresting :: M.Map Int Int -> Int
countInteresting m = length $ filter isInteresting (M.elems m)

doit :: Int -> [Int]
doit n = parMap rseq countInteresting (M.splitRoot $ theMap n)

main :: IO ()
main = do
  ( arg1 : _) <- getArgs
  let n = read arg1
  print $ doit n

请注意,但这些警告:

  • 分割的大小可能不同
  • 如果使用Map有助于您的计算,请使用splitRoot;这个特殊的例子并没有从root的Map结构中受益 - 它可能只是在元素上进行parMap。