2017-06-20 41 views
0

這是用我的第一次OpenMP和我覺得我有在下面的執行核心誤區:OpenMP的總和解釋

#include <omp.h> 
#include <stdio.h> 

int main(int argc, char *argv[]) { 

int i, n; 
float a[100], b[100], result; 

/* Some initializations */ 
n = 100; 
result = 0.0; 
for (i=0; i < n; i++) { 
    a[i] = i * 1.0; 
    b[i] = i * 2.0; 
    } 

    //pragma statement for omp here 
    for (int i=0; i < n; i++) 
    result = result + (a[i] * b[i]); 

printf("Final result= %f\n",result); 

} 

該計劃的目的是計算一個點積它涉及的總和。 在this question回答的人建議使用減法來實現for循環中的並行求和使用#pragma omp parallel for reduction(+:results)然而在實驗時我得到的答案與我剛纔使用的#pragma omp parallel for相同,我天真地認爲它是正確的,但留給我的是一種不安的感覺因爲我找不到任何文件說這是不正確的。對我爲什麼可能錯誤的解釋會有所幫助。

+2

你的程序不可能是錯的,它肯定是錯的。 'result'的更新是由所有線程進行的,沒有同步。該計劃有一個規範的*數據競賽*。到目前爲止,你已經很幸運了(是的,正確),看不到這一點。嘗試增加'n'到'10^6',看看會發生什麼。 –

回答

3

使用#pragma omp parallel for reduction(+:result)是正確的。 #pragma omp parallel for是錯誤的。後者意味着所有線程都以不受保護的方式寫入result。這是一個classical race condition。在實踐中,你可能會得到相同的結果,例如因爲硬件工作原理上,操作系統不會在不同的內核上安排線程,或者只是純粹的運氣。不要被愚弄,代碼仍然是錯誤的。

不幸的是,你不能證明代碼是正確的,只是顯示它產生正確的結果一些時間。只是所以你不能通過測試顯示兩個代碼是相同的,讓他們幾次產生相同的結果。或者換句話說,不正確的代碼並不總是容易顯示。