2015-12-13 22 views
2

我試圖實現一個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, jk似乎是未初始化:

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編譯器,以查看它是否可能是他們的錯誤。

回答

0

Cilk運行時使用遞歸分割和征服算法來並行化循環。本質上,它將範圍減半,並遞歸地自我調用兩次,產生一半並調用一半。

作爲初始化的一部分,它會計算一個「粒度」,它是最小尺寸的大小,它會打破你的範圍。默認情況下,這是loopRange/8P,其中P是核心數量。

一個有趣的實驗。將Cilk的工人數量設置爲1。當你做到這一點,所有的cilk_for機制是excersized,但因爲只有1名工人說,沒有東西被盜。

另一種可能性是嘗試在Cilkscreen(Cilk競爭對手檢測器)下運行您的代碼。不幸的是,只有GCC的cilkplus分支生成Cilkscreen需要的註釋。您的選擇是使用英特爾commpiler,或嘗試使用GCC 4.9的cilkplus分支。有關如何下載代碼並構建它的指導位於cilkplus.org website

1

關於cilk_for中的浮點異常,在某些版本的Cilk Plus運行時中已經修復了一些問題。是否有可能使用過時的版本?

https://software.intel.com/en-us/forums/intel-cilk-plus/topic/558825

此外,什麼是所產生的特定的警告消息?舊版本的Cilk Plus GCC發生了一些「未初始化的變量」警告,我認爲這些警告是虛假警告。