我试图理解为什么我们需要标准示例代码的所有部分:
a `par` b `pseq` a+b
为什么以下内容还不够?
a `par` b `par` a+b
上面的表达式似乎非常具有描述性:尝试同时计算两者a
并b
返回结果a+b
。只是效率的原因:第二个版本会触发两次而不是一次?
下面的更简洁的版本怎么样?
a `par` a+b
为什么我们需要确保在原始标准代码中b
进行评估?a+b
我试图理解为什么我们需要标准示例代码的所有部分:
a `par` b `pseq` a+b
为什么以下内容还不够?
a `par` b `par` a+b
上面的表达式似乎非常具有描述性:尝试同时计算两者a
并b
返回结果a+b
。只是效率的原因:第二个版本会触发两次而不是一次?
下面的更简洁的版本怎么样?
a `par` a+b
为什么我们需要确保在原始标准代码中b
进行评估?a+b
好的。我认为以下论文回答了我的问题: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
确保主线程b
之前 a+b
工作(否则会开始评估a
),从而使火花有机会实现a
到线程中以进行并行评估。
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