我試圖實現一個2D模板算法,操縱矩陣。對於矩陣中的每個字段,其上下左右的字段將被添加併除以4以計算新值。對於給定的矩陣,這個過程可能會迭代多次。Paralellized執行嵌套使用Cilk
該程序是用C編寫的,並用cilkplus gcc二進制編譯。
**編輯:我想你可能會感興趣的編譯器標誌:
~/cilkplus/bin/gcc -fcilkplus -lcilkrts -pedantic-errors -g -Wall -std=gnu11 -O3 `pkg-config --cflags glib-2.0 gsl` -c -o sal_cilk_tst.o sal_cilk_tst.c
請注意:真正代碼涉及到一些指針運算把一切都保持一致。順序執行工作。我在此省略這些步驟以增強可理解性。
僞代碼看起來像這樣(沒有邊緣的情況下處理):
for(int i = 0; i < iterations; i++){
for(int j = 0; j < matrix.width; j++){
for(int k = 0; k < matrix.height; k++){
result_ matrix[j][k] = (matrix[j-1][k] +
matrix[j+1][k] +
matrix[j] [k+1] +
matrix[j] [k-1])/4;
}
}
matrix = result_matrix;
}
的模板計算則本身轉移到功能apply_stencil(...)
for(int i = 0; i < iterations; i++){
for(int j = 0; j < matrix.width; j++){
for(int k = 0; k < matrix.height; k++){
apply_stencil(matrix, result_matrix, j, k);
}
}
matrix = result_matrix;
}
和並行化嘗試:
for(int i = 0; i < iterations; i++){
for(int j = 0; j < matrix.width; j++){
cilk_for(int k = 0; k < matrix.height; k++){ /* <--- */
apply_stencil(matrix, result_matrix, j, k);
}
}
matrix = result_matrix;
}
此版本無誤地編譯s /警告,但是直接執行時會產生一個Floating point exception
。如果你想知道:哪個for循環被做成cilk_for循環並不重要。所有的配置(除了沒有cilk_for)都會產生相同的錯誤。
可能的另一種方法:i, j
和k
似乎是未初始化:
for(int i = 0; i < iterations; i++){
for(int j = 0; j < matrix.width; j++){
for(int k = 0; k < matrix.height; k++){
cilk_spawn apply_stencil(matrix, result_matrix, j, k); /* <--- */
}
}
cilk_sync; /* <--- */
matrix = result_matrix;
}
編譯時這將產生3個警告。 嘗試執行時,執行matrix = result_matrix;
步驟的函數似乎未定義。
現在爲了真正的問題:爲什麼以及如何Cilk打破我的順序代碼;或者說我怎麼能阻止它這樣做呢?
實際的代碼當然也可用,如果你有興趣。然而,這個項目是針對一個大學的課程,因此受到其他學生的剽竊,他們發現這個主題,這就是爲什麼我不願意公開分享它的原因。
**更新:
至於建議我嘗試只有1工作者線程運行算法,有效地使Cilk的執行順序。這確實,出人意料的是,工作得很好。但是,只要我將工人數量改爲兩人,熟悉的錯誤就會返回。
我不認爲這種行爲是由種族條件引起的。由於工作矩陣在每次迭代後被改變並且調用cilk_sync
,所以實際上沒有關鍵部分。所有線程都不依賴於其他人在同一次迭代中寫入的數據。
我將嘗試的下一步是嘗試其他版本的cilkplus編譯器,以查看它是否可能是他們的錯誤。