【发布时间】:2015-08-04 03:50:16
【问题描述】:
我有一组问题想要并行评估。这些问题使用与此非常相似的简单表达式类型来表达:
-- 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
最后,我解决了将返回[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 ()
基本思想是我从标准输入读取一个数字列表和一个目标数字,然后在标准输出上打印表达式。
但我有两个问题想要解决,但我不太确定它们之间的相关性:
这些启发式算法完全不知道彼此,因此不知道他们的解决方案的
score是否高于其他任何方法。我想为 map 函数引入某种状态,只打印新的Expr,如果它的分数高于之前打印的Expr。我想并行执行这些计算,并尝试使用
(parMap rseq)而不是map,使用-threaded选项编译并使用+RTS -N2运行它。结果是运行时间从 5 秒增加到 7 秒。不是我所期望的,尽管time显示 CPU 利用率更高。我想我没有正确使用parMap或使用++做错了什么。那么我将如何并行运行一个独立函数列表,每个函数返回一个元素列表?
【问题讨论】:
-
使用
rdeepseq代替rseq有什么不同吗? -
这给了我
No instance for (NFData (IO ())) arising from a use ofrdeepseq'`。 -
您介意发布所有代码吗(也许在链接中?)我有一个想法,但我想先测试一下
-
@MarcusRiemer 嗯,你在哪里使用
rseq?我在问题中给出的代码中没有看到它。如果您想并行运行IO,也许您需要async包。 -
@jozefg:我上传了一个相当粗略的版本到gist.github.com/anonymous/f85737334dac2c710f00。
标签: haskell parallel-processing