【发布时间】:2013-02-06 23:28:45
【问题描述】:
Haskell 是函数式且纯粹的,因此基本上它具有编译器能够处理 implicit parallelism 所需的所有属性。
考虑这个简单的例子:
f = do
a <- Just 1
b <- Just $ Just 2
-- ^ The above line does not utilize an `a` variable, so it can be safely
-- executed in parallel with the preceding line
c <- b
-- ^ The above line references a `b` variable, so it can only be executed
-- sequentially after it
return (a, c)
-- On the exit from a monad scope we wait for all computations to finish and
-- gather the results
执行计划的示意图可以描述为:
do
|
+---------+---------+
| |
a <- Just 1 b <- Just $ Just 2
| |
| c <- b
| |
+---------+---------+
|
return (a, c)
为什么编译器中还没有使用标志或编译指示实现这样的功能?有哪些实际原因?
【问题讨论】:
-
do { rc1 <- system("/usr/games/tetris") ; rc2 <- system("rm -rf /") }?? -
因为您在
Maybemonad 中,所以在您的 do 块中有b对a的隐式依赖。b <- ...只会在a未绑定到Nothing的情况下执行。 -
@NikitaVolkov 实际上,我的回答可以解释为对 n.m. 的支持。从某种意义上说,尝试评估绑定到
b的表达式是安全的,但可能不会使用该结果。 -
@sabauma 哦,对,误会你了。但是
b可以乐观地计算,因为知道在mzero的情况下它将被丢弃。是的,开销,但我们谈论的是编译器选项,而不是默认行为。 IMO 为节省开发时间付出的代价是值得的。除了这只是一个例子,这里还有另一个:map (+2) [0,1,2,3] -
我认为值得注意的是,即使没有 Haskell 编译器提供隐式并行性(据我所知),也有一些库可以提供,例如
repa。我认为 sabauma 的回答是正确的:如果没有一些额外的领域知识,那么隐式并行性何时是有利的,这是一个悬而未决的问题。
标签: haskell concurrency parallel-processing compiler-optimization