【问题标题】:Automatic parallelism in Haskell [duplicate]Haskell中的自动并行性[重复]
【发布时间】:2014-11-22 22:37:02
【问题描述】:

在 haskell 中,假设我有以下形式的函数调用:foo a b,其中a 不依赖于b,反之亦然。似乎可以自动检测到 ab 可以并行评估,但在 GHC 中似乎并非如此。相反,需要使用像 par 这样的结构来表示可以并行评估的内容。

那么,为什么haskell 中的并行化不能自动发生呢?或者如果它已经存在,为什么还会存在 par 这样的结构?

【问题讨论】:

  • 自动并行的问题在于它增加了开销,并且很难自动确定两个表达式的并行评估是否会带来好处。
  • @PetrPudlák 所以问题不在于该原理不起作用,而是它的收益不是很大,甚至可能会变慢?

标签: haskell parallel-processing


【解决方案1】:

似乎可以自动检测到a和b可以并行计算

正如您所暗示的,通过查看值之间的依赖关系,可以自动检测并行性。在不涉及副作用的情况下,这尤其容易。

问题在于知道何时停止使事情并行化。

这一切都归结为在编译时知道运行时会发生多少工作。这些“成本模型”通常很难用于任意代码。

考虑:

  • 是否应该并行评估 (+) 的每个参数?
  • 是否应该并行评估每张地图?

如果我们天真地并行化所有独立计算,编译器将生成大量并行任务。数百万或数十亿个并行表达式。我们的 8 或 16 核机器还没有准备好处理。

简单的并行化会导致大量开销试图将工作安排到少量可用的并行硬件上。

纯程序的并行量与可用硬件之间的差距迫使我们做出一些妥协。即:

  1. 用户注释的提示,说明哪些事情的成本足够高 并行
  2. 具有明确成本模型的语言子集,因此编译器可以很智能。

第一种形式的示例 -- 用户提示 -- are par annotationsPar monad。 第二种——自动并行的子语言——见Data Parallel Haskell

【讨论】:

  • 这个答案假定要么(a)有一个非常幼稚的运行时环境,盲目地产生任务和/或(b)它必须在编译时知道多少并行度必须在哪里介绍。它并没有指出自动并行(在 Haskell 中)只是一个未解决的问题,而不是一个 unsolvable 的问题。 (a) 为什么不能,例如(固定池)工作线程根据现有线程的运行时堆栈确定自己可以去哪里做一些工作? (b) 为什么必须在编译时知道必须发生并行化的位置?
  • 我不明白为什么我们不能,例如用 C/C++ 编写一个 Haskell 风格的函数式(副作用和无状态)程序,然后使用例如Cilkspawnsync 关键字在每个子函数调用(abfoo a b 示例中),然后是 sync,然后在结果上计算 foo a' b'。关键字只是提示,如果所有工作线程都已忙,运行时会忽略它们。似乎是理想的解决方案...
猜你喜欢
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 2011-01-13
  • 2014-08-22
  • 2019-02-20
  • 1970-01-01
相关资源
最近更新 更多