为什么我的for循环的cilk_spawn比我的cilk_for循环更好?

时间:2014-04-23 21:20:28

标签: c++ cilk-plus

我有

cilk_for (int i = 0; i < 100; i++)
   x = fib(35);

以上需要6.151秒

for (int i = 0; i < 100; i++)
   x = cilk_spawn fib(35);

需要5.703秒

fib(x)是可怕的递归Fibonacci数函数。如果我向下调整fib函数cilk_for的效果优于cilk_spawn,但在我看来,无论执行fib(x) cilk_for所需的时间都应该比cilk_spawn更好。

我不明白什么?

1 个答案:

答案 0 :(得分:2)

根据评论,问题是缺少cilk_sync。我将对此进行扩展,以确切地指出如何以惊人的准确度预测时间比率。

在具有P硬件线程的系统上(通常在i7上为8),/ cilk_spawn代码将按如下方式执行:

  1. 初始线程将执行i = 0的迭代,并留下被其他线程窃取的延续。
  2. 每个小偷都会窃取一次迭代并为下一次迭代留下延续。
  3. 当每个小偷完成一次迭代时,它会回到第2步,除非没有更多的迭代来窃取。
  4. 因此,线程将手动执行循环,并且循环在P-1线程仍然在迭代上工作的点退出。因此,在仅评估(100-P-1)次迭代后,可以预期循环完成。

    因此,对于8个硬件线程,缺少cilk_sync的for / cilk_spawn应该花费大约93/100的时间用于cilk_for,非常接近观察到的比率约为5.703 / 6.151 = 0.927。

    相反,在一个孩子偷窃&#34;系统如TBB或PPL task_group,循环将竞争完成,生成100个任务,然后继续前进,直到调用task_group :: wait。在这种情况下,忘记同步会导致更加激烈的时间比例。