簡體   English   中英

使用嵌套for循環進行OpenMP雙精度縮減

[英]OpenMP double reduction with nested for loops

我開始學習OpenMP,我無法處理這段代碼。 每次運行時都會給出不同的結果。

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

int main() {
    int numsmp = 10;
    double d = 0.0;
    double d1 = 0.0;
    float trace[10];
    #pragma omp parallel for num_threads(2) reduction(+ : d, d1)
    for (int i = 0; i < numsmp; i++) {
        for (long int k = 0; k < 2; k++) {
            printf("\n");
            d++;
            printf("i  = %d k = %d d = %lf", i, k, d);
        }
        d1 += d;
        trace[i] = d;
    }
    for (int i = 0; i < 10; i++) {
        printf("\n%lf", trace[i]);
    }
    printf("d1=%f\n", d1);
}

我會注意到,在我的機器上,它似乎給出了一致(但明顯錯誤)的結果(60而不是110) - 但這可能是不同的機器,它也可能取決於當前的系統負載。

您的問題是您正在使用其中一個縮減變量d來計算另一個。 OpenMP減少將為每個線程創建一個局部變量(在這種情況下,每個線程將有一個本地dd1 )並在最后將它們加在一起。

在你的情況下,如果運行此沒有順序,你將以下值相加dd12, 4, 6, 8, 10, 12, 14, 16, 18, 20 ,但如果用2運行它螺紋(誰,讓我們假設,均勻地分擔負載)它們中的每將總結其本地的下列值d到他們的本地 d12, 4, 6, 8, 10 之后,代碼將對每個線程的本地d1求和,以給出最終結果。

為了檢查我們的推理,我們可以自己嘗試總和,單線程總和應該給我們110,代碼也是。 然后使用2個線程(假設均勻負載分配)應該給我們2x30 = 60,這也是。

我將假設這只是一個非常好的最小例子,所以我不能建議你應該如何去解決你想做的事情。 但在這種情況下,你可以簡單地從i計算d 如果這種情況不可能(在某些其他情況下),您可以使用critical區域,但這些並不總是一個好的解決方案(取決於問題)。

關於減少的進一步閱讀可以(例如)在這里找到: http//pages.tacc.utexas.edu/~eijkhout/pcse/html/omp-reduction.html

暫無
暫無

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

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