kir*_*kun 30 parallel-processing haskell speculative-execution
我试图理解为什么我们需要标准示例代码的所有部分:
a `par` b `pseq` a+b
Run Code Online (Sandbox Code Playgroud)
以下为什么不够?
a `par` b `par` a+b
Run Code Online (Sandbox Code Playgroud)
上述表达式似乎很描述:尝试同时评估a
和b
并行,并返回结果a+b
.仅仅是效率的原因:第二个版本会引发两次而不是一次?
以下,更简洁的版本怎么样?
a `par` a+b
Run Code Online (Sandbox Code Playgroud)
为什么我们需要确保在原始标准代码b
之前进行评估a+b
?
kir*_*kun 30
好.我想以下文章回答了我的问题:http://community.haskell.org/~simonmar/papers/threadscope.pdf
总之,问题所在
a `par` b `par` a+b
Run Code Online (Sandbox Code Playgroud)
和
a `par` a+b
Run Code Online (Sandbox Code Playgroud)
是缺乏评估的顺序.在这两个版本中,主线程立即a
(或有时b
)立即工作,导致火花立即"消失",因为不再需要启动线程来评估主线程已经开始评估的内容.
原始版本
a `par` b `pseq` a+b
Run Code Online (Sandbox Code Playgroud)
确保主线程在b
之前工作 a+b
(否则就会开始评估a
),从而使spark有机会a
实现并行评估的线程.
Alp*_*ari 16
a `par` b `par` a+b
Run Code Online (Sandbox Code Playgroud)
将并行评估a和b并返回a + b,是的.
然而,PSEQ有确保前A和B两者进行评估A + B是.
a `par` b `par` a+b
两者产生火花a
和b
,但a+b
被立即达到这样的火花的人会以失败告终(即,它在主线程中进行评估).问题在于效率,因为我们创造了不必要的火花.如果您使用它来实现并行分而治之,则开销将限制您的加速.
a `par` a+b
似乎更好,因为它只会产生一个火花.然而,试图评估a
之前b
将失去火花a
,并且由于b
没有火花,这将导致顺序评估a+b
.切换顺序b+a
将解决此问题,但作为代码,这不会强制执行排序,Haskell仍然可以将其评估为a+b
.
因此,我们在尝试评估之前a `par` b `pseq` a+b
强制b
在主线程中进行评估a+b
.a
在我们尝试评估之前,这给了实现的机会a+b
,并且我们没有创造任何不必要的火花.