[英]Why do we need 'seq' or 'pseq' with 'par' in Haskell?
I'm trying to understand why we need all parts of the standard sample code: 我试图理解为什么我们需要标准示例代码的所有部分:
a `par` b `pseq` a+b
Why won't the following be sufficient? 以下为什么不够?
a `par` b `par` a+b
The above expression seems very descriptive: Try to evaluate both a
and b
in parallel, and return the result a+b
. 上面的表达式似乎非常具有描述性:尝试并行计算
a
和b
,并返回结果a+b
。 Is the reason only that of efficiency: the second version would spark off twice instead of once? 仅仅是效率的原因:第二个版本会引发两次而不是一次?
How about the following, more succinct version? 以下,更简洁的版本怎么样?
a `par` a+b
Why would we need to make sure b
is evaluated before a+b
as in the original, standard code? 为什么我们需要确保
b
前计算a+b
为在原有标准码?
Ok. 好。 I think the following paper answers my question: http://community.haskell.org/~simonmar/papers/threadscope.pdf
我想以下文章回答了我的问题: http : //community.haskell.org/~simonmar/papers/threadscope.pdf
In summary, the problem with 总之,问题所在
a `par` b `par` a+b
and 和
a `par` a+b
is the lack of ordering of evaluation. 是缺乏评估的顺序。 In both versions, the main thread gets to work on
a
(or sometimes b
) immediately, causing the sparks to "fizzle" away immediately since there is no more need to start a thread to evaluate what the main thread has already started evaluating. 在这两个版本,主线程到达上工作
a
(或有时b
)立刻,马上引起火花“嘶”走,因为没有更需要启动一个线程来评估哪些主线程已经开始评估。
The original version 原始版本
a `par` b `pseq` a+b
ensures the main thread works on b
before a+b
(or else would have started evaluating a
instead), thus giving a chance for the spark a
to materialize into a thread for parallel evaluation. 确保主线程在
a+b
b
之前 a+b
(否则将开始评估a
),从而使spark a
有机会实现为并行评估的线程。
a `par` b `par` a+b
creates sparks for both a
and b
, but a+b
is reached immediately so one of the sparks will fizzle (ie, it is evaluated in the main thread). a `par` b `par` a+b
创建两个火花a
和b
,但是a+b
则立即进入所以火花之一将结果失败(即,它在主线程进行评价)。 The problem with this is efficiency, as we created an unnecessary spark. 问题在于效率,因为我们创造了不必要的火花。 If you're using this to implement parallel divide & conquer then the overhead will limit your speedup.
如果您使用它来实现并行分而治之,则开销将限制您的加速。
a `par` a+b
seems better because it only creates a single spark. a `par` a+b
似乎更好,因为它只会产生一个火花。 However, attempting to evaluate a
before b
will fizzle the spark for a
, and as b
does not have a spark this will result in sequential evaluation of a+b
. 然而,试图评价
a
前b
将会以失败告终火花的a
,和b
不产生火花,这将导致顺序计算a+b
。 Switching the order to b+a
would solve this problem, but as code this doesn't enforce ordering and Haskell could still evaluate that as a+b
. 将顺序切换为
b+a
将解决此问题,但作为代码,这不会强制执行排序,Haskell仍然可以将其评估为a+b
。
So, we do a `par` b `pseq` a+b
to force evaluation of b
in the main thread before we attempt to evaluate a+b
. 所以,我们做
a `par` b `pseq` a+b
给力的评价b
在主线程之前,我们试图评估a+b
。 This gives the a
spark chance to materialise before we try evaluating a+b
, and we haven't created any unnecessary sparks. 在我们尝试评估
a+b
之前,这给了实现a
机会,并且我们没有创造任何不必要的火花。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.