Haskell 并行最大值计算

Haskell 并行最大值计算,haskell,parallel-processing,Haskell,Parallel Processing,我有一组问题,我想同时进行评估。这些问题使用一个简单的表达式类型表示,非常类似于: -- Expressions are either a constant value or two expressions -- combined using a certain operation data Expr = Const NumType | Binary BinOp Expr Expr -- The possible operations data BinOp = Add | S

我有一组问题,我想同时进行评估。这些问题使用一个简单的表达式类型表示,非常类似于:

-- Expressions are either a constant value or two expressions
-- combined using a certain operation
data Expr 
    = Const NumType
    | Binary BinOp Expr Expr

-- The possible operations
data BinOp = Add | Sub | Mul | Div
    deriving (Eq)
这些表达式是动态构建的,计算结果可能有效,也可能无效。当遇到无效结果时,它被表示为停止计算的monad

data Result a
    = Val { val :: a }
    | Exc { exc :: String }

instance Monad Result where
    return = Val
    (Exc e) >>= _ = (Exc e)
    (Val v) >>= g = g v
要确定每个已解决问题的值,我有两个相关函数:

eval :: Expr -> Result NumType
score :: Expr -> NumType
最后,我有一些solve函数,它们将返回一个
[Expr]
。这导致我目前的主要功能如下:

main :: IO ()
main = do
    strAvailableNumbers <- getLine
    strTargetNumber <- getLine
    let numbers = parseList strAvailableNumbers 
        target = parseTargetNumber strTargetNumber in
            sequence $ map (print) $ 
                solveHeuristic1 (Problem target numbers) [Add] [Sub] ++
                solveHeuristic2 (Problem target numbers) 

    return ()
main::IO()
main=do

strAvailableNumbers这里的问题是,使用
seq
评估
IO
操作几乎没有任何作用。因此,您只是以稍微高一点的开销按顺序运行

你可以折射物体,使其再次纯净

main :: IO ()
main = do
    mapM_ (`seq` print "found it") -- make sure we're not 
                                   -- benchmarking printing stuff
          . concat
          . parMap rdeepseq (solve [1..10000000])
          $ [42, 42]

    return ()
并添加
NFData
的实例以使用
rdeepseq
,这将全面评估事物

instance NFData BinOp -- Binop is just an enum, WHNF = NF

instance NFData Expr where
  rnf (Const a) = a `deepseq` ()
  rnf (Binary b e1 e2) = b `deepseq` e1 `deepseq` e2 `deepseq` ()
现在如果我们运行它,我们会得到。。。堆垛机溢出。我增加了足够的大小,以便我们进行搜索,以使它花费足够长的时间来进行基准测试,现在将这两个结构完全加载到内存中将使堆栈崩溃。使用
-N2
时,如果将堆栈大小增加到不破坏所有内容的程度,则运行速度将提高40%(3秒对5秒)。我会考虑预期的结果。在运行这个程序时,我可以看到2个内核短暂地跃升到100%

最终编译顺序

> ghc -O2 -threaded -rtsops bench.hs
> ./bench +RTS -K10000000 -N2

使用
rdeepseq
而不是
rseq
会有什么不同吗?这给了我
一个使用
rdeepseq``而产生的(NFData(IO())实例。你介意发布所有代码吗(可能在链接中?)我有一个想法,但我想测试一下first@MarcusRiemer嗯,你在哪里使用
rseq
?我在问题中给出的代码中没有看到它。如果你想并行运行
IO
,也许你想要的是
async
包。@jozefg:我上传了一个相当粗糙的版本到。