簡體   English   中英

順序和並行版本給出不同的結果 - 為什么?

[英]Sequential and parallel versions give different results - Why?

我有一個嵌套循環:(L 和 A 是完全定義的輸入)

    #pragma omp parallel for schedule(guided) shared(L,A) \
    reduction(+:dummy)
    for (i=k+1;i<row;i++){
            for (n=0;n<k;n++){
                #pragma omp atomic
                dummy += L[i][n]*L[k][n];
                L[i][k] = (A[i][k] - dummy)/L[k][k];
            }
            dummy = 0;
    }

及其順序版本:

    for (i=k+1;i<row;i++){
            for (n=0;n<k;n++){
                dummy += L[i][n]*L[k][n];
                L[i][k] = (A[i][k] - dummy)/L[k][k];
            }
            dummy = 0;
    }

他們都給出不同的結果。 並行版本比順序版本慢得多。

什么可能導致問題?

編輯:

為了擺脫原子指令引起的問題,我修改了代碼如下:

#pragma omp parallel for schedule(guided) shared(L,A) \
    private(i)
    for (i=k+1;i<row;i++){
        double dummyy = 0;
        for (n=0;n<k;n++){
            dummyy += L[i][n]*L[k][n];
            L[i][k] = (A[i][k] - dummyy)/L[k][k];
        }
    }

但它也沒有解決問題。 結果還是不一樣。

我對 OpenMP 不太熟悉,但在我看來,您的計算與順序無關。 即,將內循環的結果寫入L[i][k] ,其中ik是內循環的不變量。 這意味着同一值在內循環中被覆蓋k次,從而導致競爭條件。

此外, dummy似乎在不同線程之間共享,因此那里也可能存在競爭條件,除非您的 pragma 參數以某種方式阻止它。

總之,在我看來,如果您想要順序執行給出的結果相同,則內部循環中的計算必須以相同的順序執行。 因此只有外部循環可以並行化。

在您的並行版本中,您插入了一個不必要的(並且可能有害的)原子指令。 一旦您將dummy聲明為縮減變量,OpenMP 就會負責停止干擾縮減的線程。 我認為不必要的指令的主要影響是大大降低了代碼速度。

我看到您有另一個解決結果錯誤的答案。 但是我注意到你似乎在每次外循環迭代結束時將dummy設置為0 ,如果你試圖將它用作某種累加器,這似乎很奇怪,這就是 reduction 子句所建議的。 也許您想減少內部循環的dummy

如果您在還原方面遇到問題,請閱讀此

結果的差異來自內部循環變量n ,它在線程之間共享,因為它是在 omp pragma 之外定義的。

澄清:循環變量n應該在 omp pragma 中聲明,因為它應該是特定於線程的,例如for (int n = 0;.....)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM