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

时间:2011-01-02 02:00:47

标签: haskell parallel-processing speculative-execution

我试图理解为什么我们需要标准示例代码的所有部分:

a `par` b `pseq` a+b

为什么下列内容不够?

a `par` b `par` a+b

上述表达式似乎非常具有描述性:尝试并行评估ab,并返回结果a+b。仅仅是效率的原因:第二个版本会引发两次而不是一次吗?

以下更简洁的版本怎么样?

a `par` a+b

为什么我们需要确保在b之前评估a+b与原始标准代码一样?

3 个答案:

答案 0 :(得分:30)

确定。我认为以下文件回答了我的问题:http://community.haskell.org/~simonmar/papers/threadscope.pdf

总之,

的问题
a `par` b `par` a+b 

a `par` a+b

缺乏评估顺序。在这两个版本中,主线程立即在a(或有时b)上工作,导致火花立即“消失”,因为不再需要启动线程来评估主线程已经开始评估。

原始版本

a `par` b `pseq` a+b

确保主线程在<{strong> b之前a+b 上运行(否则会开始评估a),从而为spark提供机会{ {1}}实现了一个并行评估的线程。

答案 1 :(得分:16)

a `par` b `par` a+b 

将并行评估a和b并返回 a + b ,是的。

然而, pseq 确保 a&b>在 a + b 之前评估a和b。

有关该主题的详细信息,请参阅this link

答案 2 :(得分:6)

a `par` b `par` a+bab创建了火花,但是a+b会立即到达,因此其中一个火花会失败(即,它会在主线程中进行评估) )。问题在于效率,因为我们创造了不必要的火花。如果您正在使用此功能来实现并行分频&amp;征服然后开销将限制你的加速。

a `par` a+b似乎更好,因为它只会产生一个火花。但是,尝试在a之前评估b会失去a的火花,并且由于b没有火花,这将导致对{{1}的顺序评估}。将订单切换为a+b可以解决此问题,但是作为代码,这不会强制执行排序,而Haskell仍然可以将其评估为b+a

因此,在我们尝试评估a+b之前,我们会a `par` b `pseq` a+b强制评估主线程中的b。在我们尝试评估a+b之前,这会让a火花机会成为现实,而且我们还没有创造出任何不必要的火花。