简体   繁体   English

为什么我们在Haskell中需要'seq'或'pseq'和'par'?

[英]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 . 上面的表达式似乎非常具有描述性:尝试并行计算ab ,并返回结果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 

will evaluate a and b in parallel and returns a+b , yes. 将并行评估a和b并返回a + b ,是的。

However, the pseq there ensures both a and b are evaluated before a+b is. 但是, pseq 确保a + b之前评估a和b

See this link for more details on that topic. 有关主题的更多详细信息,请参阅此链接

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创建两个火花ab ,但是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 . 然而,试图评价ab将会以失败告终火花的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM