虽然我正在学习cilk,但我反驳了两个相反的例子:
对立面就是这两行:
x = spawn fib (n-1);
y = spawn fib (n-2);
第一个网站说:
您不需要将cilk_spawn属性添加到第二个递归 拨打
fib()
,因为这会创建一个空的延续
答案 0 :(得分:3)
来自英特尔文档的代码“int x = cilk_spawn fib(n-1);”请求允许在另一个威胁中运行它,而下一行“int y = fib(n-2);”将与主程序运行相同的威胁。维基代码也要求计算fib(n-2)的新威胁,以便如果有超过三个处理器来运行主程序(fib(n)),fib(n-1)和fib(n-2) )所有的单独威胁。
如果只有两个处理器,两个代码将执行相同的操作。以下内容来自维基页面:
......处理者没有义务在其他地方分配衍生程序; 如果机器只有两个处理器而第二个仍然忙于fib(1)当执行fib(2)的处理器进入程序调用时,第一个处理器将暂停fib(2)并执行fib(0)本身,就像它是唯一的处理器一样。当然,如果另一个处理器可用,那么它将被调用到服务中,并且所有三个处理器将同时执行单独的帧。
答案 1 :(得分:1)
您所指的维基百科中的示例来自MIT Cilk,它要求生成对Cilk函数的所有调用。 Cilk ++取消了这一要求,后者演变为英特尔的Cilk Plus实施。
请记住,这是被盗的延续,而不是衍生的功能。在生成函数之前执行代码的worker将执行派生函数。 cilk_spawn
将继续推送到工人的双端队列,使其可供闲置工人偷窃。
考虑在Cilk Plus中完全实现fib:
int fib(int n) {
if (n < 2)
return n;
int x = cilk_spawn fib(n-1);
int y = fib(n-2);
cilk_sync;
return x+y;
}
如果你对第二次递归调用放置cilk_spawn
,那么你就是允许空闲工作者在该调用之后窃取延续。但是这条链立即在cilk_sync
结束,所以这是浪费时间。