下面的代码是怎样的:
parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `par` (nf1+nf2+1))
where nf1 = parfib (n-1)
nf2 = parfib (n-2)比这更好:
parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `seq` (nf1+nf2+1))
where nf1 = parfib (n-1)
nf2 = parfib (n-2)我在网上找不到这样的解释:“为了保证主表达式以正确的顺序计算(即不阻塞子任务上的主任务),使用了seq注释”。
为什么使用seq?我知道这会迫使解释器首先计算parfib (n-1),但是为什么要这样做呢?
当执行第二个程序时,插入器不会触发一个新的进程来计算nf2,同时并行计算nf1+nf2+1表达式的nf1吗?有什么必要告诉它指定它应该以nf1开头?
发布于 2009-04-03 10:54:41
将nf1与nf1+...并行评估没有多大意义,因为后者依赖于nf1,所以它所做的就是阻止nf1的火花。使用seq时,它只会在您知道nf1已被评估后才尝试使用它。
发布于 2009-06-06 20:46:10
这可能是因为我们想要最小化火花的数量,从我的理解是,两次碰撞将产生相同的结果。
但是对于第一个选项,您将触发两个额外的进程(nf1,nf2)。但是当我们使用seq时,我们只触发了一个额外的进程( nf1)。
https://stackoverflow.com/questions/713150
复制相似问题