Parse Monad与Eval Monad之间的差异与deepseq

时间:2014-04-27 17:55:10

标签: haskell parallel-processing

我一直在阅读Simon Marlow在Haskell中的并行和并发Progaramming(很棒的书btw ..)并且他声明Eval Monad只是并行评估惰性数据结构,而Par Monad是为避免依赖lazy而创建的评价。但是使用Eval Monad,您可以使用deepseqforce来获得完全评估的数据结构,即非惰性数据结构。那么除了与Eval Monad相关的不同编程模型之外,Par Monad的价值主张是什么?

1 个答案:

答案 0 :(得分:9)

Glasgow Parallel Haskell中的并行性可以使用par组合子来表示潜在的并行性(类似于懒惰期货)和seq组合子来指定评估顺序。这是一种非结构化的并行编程方法,因为它需要程序员理解语言的操作属性(部分依赖于实现)并将组合器插入算法代码中。因此,评估策略已被引入(Algorithm + Strategy = Parallelism,Trinder等,1998),分离计算和通信问题并提供可组合< / em>抽象(超过par和seq)而不会以非严格语言破坏模块性 Eval Monad 被设计用于解决与垃圾收集器的不良交互,这可能导致丢失的并行性或空间泄漏(详情:Seq no More: Better Strategies for Parallel Haskell,Marlow等,2010)。

Eval Monad中的并行性是 Advisory ,即运行时系统(RTS)可以自由地丢弃创建的 spark (或者thunk,指向一个没有评估的关闭),如果 并行评估它是没有益处的。这允许父任务包含任务,从而启用动态和隐式粒度控制(显式应用程序级技术,如 chunking thresholding 可以帮助RTS进一步减少并行度并增加粒度)。因此,并行性与处理器数量无关,因为处理器越多,实际任务(轻量级线程)中的火花就越多。

Par Monad专为粗粒度并行而设计,受数据流模型的影响(详见:A Monad for Deterministic Parallelism,Marlow等,2011)。介绍它是为了解决直接使用parseq的一些明显缺点。作者声称,懒惰往往会妨碍成本估算(在非严格的设置中更难)。常见的缺陷包括:将已经评估的值传递给par,而不是确保程序的其余部分稍后需要并行评估的值,或者不严格地推断严格性(参见具体示例的文章)。 Par Monad避免了懒惰问题,并在使用惰性数据结构对算法不重要的情况下帮助进行高效的并行编程。

Par Monad使用fork(或spawn)明确并强制创建(子)任务(显式粒度控制;为程序员提供更多控制权,但可以考虑到更低级别并且取决于处理器的数量),同时使用IVars显式管理任务间通信(表示依赖关系),而在Eval Monad中,共享是通过减少的图形隐含的(程序员)仍然需要表明程序的其余部分需要并行计算的值)。在Eval Monad中,需要理解操作属性并明智地应用强制函数,这很容易出错(引入太多严格也可能是一个问题)。通常,预定义的策略是足够的,并且可以避免大多数问题。另一种方法是在Par Monad之上定义 Algorithmic Skeletons

总之,使用评估策略可以被认为是更高级和模块化的,因为它将计算与协调分开(因此可以在不考虑协调的情况下理解算法),而Par Monad不需要程序员关于懒惰的原因(虽然仍然可以在线程之间共享延迟计算,应该避免这种情况,因为monad调度程序无法检测到在惰性计算上阻塞的线程而是安排另一个线程)。似乎Par Monad更适合粗粒度严格的数据流类计算,而如果需要延迟并且可以在顺序算法中添加并行性,则可以使用策略。 Par Monad的另一个优点是调度程序是在Haskell级别编写的,因此更易于修改(例如,由Meta-Par使用:A Meta-Scheduler for the Par-Monad Composable Scheduling for the Heterogeneous Cloud,A。Foltzer等,2012),因为Eval Monad依赖在RTS内部实现的调度程序上。策略更好地支持推测并行,因为它可以被消除 当发现垃圾收集器未被引用时,而在Par Monad中,执行所有推测并行性(例如,与parBuffer策略比较,不能从runPar返回具有并行评估的元素的惰性列表)。最后,两种模型也可以组合在一起。两种模型的关键优势是确定性,从而避免了竞争条件和死锁。