简单的并行加法器。您将指针传递给数组中的第一个元素,指向数组中最后一个元素的指针,第一个指针的元素#,以及正在操作的数组部分中的元素数。
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两条线都在某种程度上起作用,但功能失效了,我不知道为什么。有什么想法吗?
答案 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
。