[英]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減少將為每個線程創建一個局部變量(在這種情況下,每個線程將有一個本地d
和d1
)並在最后將它們加在一起。
在你的情況下,如果運行此沒有順序,你將以下值相加d
到d1
: 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
,但如果用2運行它螺紋(誰,讓我們假設,均勻地分擔負載)它們中的每將總結其本地的下列值d
到他們的本地 d1
: 2, 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.