5

par声明为:

par  :: a -> b -> b

请注意,该论点已被丢弃。为了使用 par ,您需要多次使用相同的表达式等技巧。

如果它的目的是并行执行a和b,为什么不这样定义呢?:

par  :: (a, b) -> (a, b)

获取(未评估)表达式的元组并返回相同的表达式 - 虽然它们可能在后台线程上实现。

似乎后一种模型比前者更简单。为什么选择这样的设计?

4

2 回答 2

8

在前者中,您可以轻松触发两个以上的计算,

c1 `par` c2 `par` c3 `par` c4 `pseq` something c1 c2 c3 c4

这在后者中会相当麻烦。

于 2012-04-15T22:21:40.063 回答
7

您建议的元组版本可以在 Control.Parallel.Strategies 中作为 parTuple2 找到,其类型为:

evalTuple2 :: Strategy a -> Strategy b -> Strategy (a, b)

至于为什么par是这样设计的,par是“更高级别”,正如Real World Haskell第 24 章所讨论的那样,他们并行化了快速排序:

我们代码的这些更改对于我们不需要说的所有事情来说都是显着的。

  • 要使用多少个内核。
  • 线程之间进行什么通信。
  • 如何在可用内核之间分配工作。
  • 哪些数据在线程之间共享,哪些是私有的。
  • 如何确定所有参与者何时完成。

A Monad for Deterministic Parallelism中,Marlow、Newton 和 Peyton Jones 写道:

par 运算符是一种有吸引力的语言设计,因为它利用了惰性求值和期货之间的重叠。为了实现惰性求值,我们必须对尚未求值但稍后可能需要其值的表达式进行表示;同样,未来是一种计算,其值正在被并行评估,我们可能会等待。因此,par 被认为是一种机制,用于将惰性计算注释为并行评估可能有利可图,实际上将惰性计算转变为未来

于 2012-04-16T10:12:56.243 回答