【问题标题】:What is the right way to compute Fibonacci using cilk?使用 cilk 计算斐波那契的正确方法是什么?
【发布时间】:2015-05-30 08:30:21
【问题描述】:

在学习 cilk 时,我举了两个相反的例子:

  1. From intel

  2. from wiki (or other examples in the net):

相反的是那两条线:

x = spawn fib (n-1);
y = spawn fib (n-2);

第一个网站说:

你不需要给第二个递归添加 cilk_spawn 属性 调用fib(),因为这将创建一个空的延续

  1. 我不明白为什么?
  2. 什么是正确的方法? (使用 2 个 spawn 命令还是只使用一个?)

【问题讨论】:

    标签: c++ fibonacci cilk


    【解决方案1】:

    英特尔文档“int x = cilk_spawn fib(n-1);”中的代码请求允许在另一个威胁中运行它,而下一行“int y = fib(n-2);”将在与主程序相同的威胁下运行。 wiki 代码还要求计算 fib(n-2) 的新威胁,以便如果有超过三个处理器来运行主程序 (fib(n))、fib (n-1) 和 fib(n-2 ) 都针对单独的威胁。

    如果只有两个处理器,这两个代码的执行方式相同。以下来自维基页面:

    ...处理器没有义务在别处分配衍生过程; 如果机器只有两个处理器并且当执行 fib(2) 的处理器进入过程调用时,第二个处理器仍然忙于 fib(1),第一个处理器将挂起 fib(2 ) 并执行 fib(0) 本身,就像它是唯一的处理器一样。当然,如果另一个处理器可用,那么它将被调用,并且所有三个处理器将同时执行单独的帧。

    【讨论】:

    【解决方案2】:

    您所指的 Wikipedia 中的示例来自 MIT Cilk,它要求生成对 Cilk 函数的所有调用。 Cilk++ 取消了这一要求,并演变为英特尔的 Cilk Plus 实施。

    请记住,被盗的是延续,而不是生成的函数。在派生函数之前执行代码的工作人员将执行派生函数。 cilk_spawn将 continuation 推送到 worker 的双端队列上,使其可供空闲的 worker 窃取。

    考虑在 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;
    }
    

    如果您在对 fib 的第二次递归调用中添加了 cilk_spawn,那么您将允许空闲的工作人员在该调用之后窃取延续。但那条链立即在cilk_sync 结束,所以这是浪费时间。

    【讨论】:

      猜你喜欢
      • 2016-09-01
      • 2016-08-26
      • 2013-03-31
      • 2018-06-15
      • 2020-01-18
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      • 2014-01-09
      相关资源
      最近更新 更多