Eval,rpar和rseq - 有什么好处?

时间:2016-10-05 22:06:20

标签: haskell parallel-processing

我在Haskell学习并行性。我看过这段代码:

runEval $ do
  a <- rpar (f x)
  b <- rpar (f y)
  rseq a
  rseq b
  return (a,b)

它在性能和开销方面的区别是什么?

let a = f x
let b = f y
(a, b)

即,根本不使用Eval。对我来说,第二个具有相同的性能和更少的开销。

1 个答案:

答案 0 :(得分:6)

完全取决于f的作用。如果f花费很长时间让您的系统进行计算,并且您的系统有一个备用CPU核心,则并行版本将更快完成。

如果ff n = n + 1那样微不足道,那么当然标准的单线程版本会更快。创建Haskell线程的开销相当低,但 低。 (如果你只有一个执行上下文,那么当然没有任何意义)。

请注意,如果我们将开销定义为“系统执行与计算结果无直接关系的工作”,那么第一个版本总是会有更多的“开销”。但是,如果您同时评估f xf y,即使系统在开销上“浪费”了一些执行资源,您也可能会更快完成。我们可能将并行版本的运行时间近似为:

maximum(time for f x, time for f y)  +  overhead

标准版的运行时间为:

time for f x  +  time for f y

因此,如果两个f调用的较小比并行化开销花费的时间更长,那么并行版本是值得的。

当然,实际上它可能要复杂得多。一个这样的问题:如果f xf y共享对同一个thunk的引用,那么标准顺序版本完全共享工作,而并行版本可能会意外地浪费时间让两个线程执行thunk。特别是如果f xf y的大部分工作实际减少了thunk以使f准备好应用,那么你就不会“真正”并行化这项工作根本就是(或多或少地竞争两个线程,看看哪个先完成)。

最终,您需要使用度量和判断来决定应用并行性的位置。这不是你可以盲目添加并自动获得好处的东西(否则编译器会为你做的)。

但如果你尝试并行运行两个非常简单的计算,它肯定不会给你任何好处。如果您只是在玩并行性以了解其工作原理,请尝试编写一个功能f来完成足够的工作,使您的第二个版本至少需要几秒钟才能运行,然后再看如果并行版本更快。