簡體   English   中英

如何在 while 循環中的嵌套 for 循環上使用 OpenMP?

[英]How to use OpenMP on nested for loops in a while loop?

我最近接觸了 OpenMP 和並行編程,但在正確使用它時遇到了一些問題。

我想在以下代碼上實現 OpenMP 以使其運行得更快。

int m = 101;
double e = 10;

double A[m][m], B[m][m];
for (int x=0; x<m; x++){
    for (int y=0; y<m; y++){
        A[x][y] = 0;
        B[x][y] = 1;
    }
}

while (e >= 0.0001){
    for (int x=0; x<m; x++){
        for (int y=0; y<m; y++){
            A[x][y] = 0.25*(B[x][y] - 0.2);
        }
    }
    e = 0;
    for (int x=0; x<m; x++){
        for (int y=0; y<m; y++){
            e = e + abs(A[x][y] - B[x][y]);
        }
    }    
}

我想同時運行循環而不是一個接一個地運行循環以加快運行時間。 我相信以下代碼應該可以工作,但我不確定我是否正確使用 OpenMP。

int m = 101;
double e = 10;

double A[m][m], B[m][m];
#pragma omp parallel for private(x,y) shared(A,B) num_threads(2)
for (int x=0; x<m; x++){
    for (int y=0; y<m; y++){
        A[x][y] = 0;
        B[x][y] = 1;
    }
}

while (e >= 0.0001){
    #pragma omp parallel for private(x,y) shared(A,B) num_threads(2)
    for (int x=0; x<m; x++){
        for (int y=0; y<m; y++){
            A[x][y] = 0.25*(B[x][y] - 0.2);
        }
    }
    // I want to wait for the above loop to finish computing before starting the next
    #pragma omp barrier  
    e = 0;
    #pragma omp parallel for private(x,y) shared(A,B,e) num_threads(2)
    for (int x=0; x<m; x++){
        for (int y=0; y<m; y++){
            e = e + abs(A[x][y] - B[x][y]);
        }
    }    
}

我是否有效且正確地使用 OpenMP? 另外,我不確定是否可以將 OpenMP 用於我的 while 循環,因為它需要先計算內部循環,然后才能確定它是否需要再次運行。

假設代碼有效,您可以進行以下改進:

int m = 101;
double e = 10;

double A[m][m], B[m][m];

#pragma omp parallel num_threads(2) shared(A, B)
{

    #pragma omp for
    for (int x=0; x<m; x++){
        for (int y=0; y<m; y++){
            A[x][y] = 0;
            B[x][y] = 1;
       }
    }

   while (e >= 0.0001){
    #pragma omp for
    for (int x=0; x<m; x++){
        for (int y=0; y<m; y++){
            A[x][y] = 0.25*(B[x][y] - 0.2);
        }
    }
    
    #pragma omp single
    e = 0;

    #pragma omp for reduction (+:e)
    for (int x=0; x<m; x++){
        for (int y=0; y<m; y++){
            e = e + abs(A[x][y] - B[x][y]);
        }
    }    
  }
}

無需每次都創建一個parallel region ,您可以通過僅為整個代碼創建一個來改進。 此外,由於您僅使用2線程,因此負載平衡問題並不,但是如果您要增加線程數,您可能會通過使用chunk = 1static調度獲得更好的性能。

您不需要將循環變量xy設為private ,OpenMP 會為您完成。 在你最后的嵌套循環中,你有e = e + abs(A[x][y] - B[x][y]); 所以您可能希望線程具有添加“e”的結果,因此您應該使用reduction (+:e)來減少跨線程的變量“e”。

暫無
暫無

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

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