2013-02-12 72 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