2013-02-12 80 views
0

简单并行加法器。您将指针传递给数组中的第一个元素,指向数组中最后一个元素的指针,第一个指针的元素#以及正在操作的数组的这部分中的元素数。部分线程正确计算,其他线程不是

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(第一季度),然后返回0的/垃圾一堆的元素#20-39和所有元素后。显然,x1和x2线都在某种程度上起作用,但功能崩溃了,我不知道为什么。有任何想法吗?

回答

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[80/2+0]x指向,即&x[40],但它也将设置first_pos40到该呼叫。最终你会达到n < 3,并使用累积first_pos索引。

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

+0

我想我需要传递first_pos以便跟踪未来切片应该在哪里出现。所以如果我想添加x [4:7],所以我会传递(&x [4],&x [7]),但是我必须保留那4来计算下一个片段,对不对?我想我不明白这是如何导致地址无效的。 – user1956609 2013-02-12 11:29:08

+0

确实。 ''x2 = my_func(&x [n/2 + first_pos],&x [first_pos + n-1],n/2 + first_pos,nn/2);'......对我来说像这个函数需要一个* assert(first_pos == 0); *以确保输入正确;) – Sebivor 2013-02-12 11:35:17

+0

“最终你会达到n <3,并使用累加的first_pos索引。我不遵循?当n <3时,返回值返回并且first_pos不是......累积的是什么? – user1956609 2013-02-12 11:36:50