有些线程正确计算,有些则没有

时间:2013-02-12 11:20:33

标签: c parallel-processing

简单的并行加法器。您将指针传递给数组中的第一个元素,指向数组中最后一个元素的指针,第一个指针的元素#,以及正在操作的数组部分中的元素数。

    double my_func (double *x, double *x_last, int first_pos, int n)
    {
      if (n ==1) {
        return x[first_pos];
      }
      else if (n == 2) {
        return x[first_pos] + x[first_pos+1];
      }
      else {
        double x1,x2;

        x1 = _Cilk_spawn my_func (&x[first_pos], &x[n/2+first_pos-1],first_pos, n/2);
        x2 = my_func (&x[n/2+first_pos],&x[first_pos+n-1],n/2+first_pos, n-n/2);
        _Cilk_sync;

        return x1 + x2;
      }
    }

假设我们从一个大小为80的数组开始。这对于元素#0-19(第一季度)非常有效,然后为元素#20-39和之后的所有元素返回一堆0 /垃圾。很明显,x1和x2两条线都在某种程度上起作用,但功能失效了,我不知道为什么。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

你正在将数组切错:

x1 = my_func (&x[n/2+first_pos],&x[first_pos+n-1],n/2+first_pos, n-n/2);
                    ^                                 ^
            new "base" pointer                first pos in slice?!

您无法将两者调整后的指针传递给切片的第一个元素,该元素的全局索引。你最终索引不止一次,可以这么说,导致无效地址被解除引用。

对于n = 80的情况,第二次递归调用将通过x指向元素&x[80/2+0],即&x[40],但它也会设置first_pos到那个电话的40。最终,您将达到n < 3,并使用累计first_pos进行索引。

此外,为清晰起见,如果输入数据是只读的,则应为const