【问题标题】:How to use OpenMP on nested for loops in a while loop?如何在while循环中的嵌套for循环上使用OpenMP?
【发布时间】:2017-04-20 10:02:02
【问题描述】:

我最近接触了 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 循环,因为它需要先计算内部循环,然后才能确定是否需要再次运行。

【问题讨论】:

    标签: c multithreading for-loop parallel-processing openmp


    【解决方案1】:

    假设代码有效,您可以进行以下改进:

    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 线程,因此不会出现很多 负载平衡问题,但是如果您要增加线程数,您可能会通过使用static 调度来获得更好的性能chunk = 1.

    您不需要创建循环变量xy private,OpenMP 会为您完成。在您的最后一个嵌套循环中,您有e = e + abs(A[x][y] - B[x][y]);,因此您可能希望线程具有添加“e”的结果,因此您应该使用reduction (+:e) 来减少线程间的变量“e”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-26
      • 2023-03-02
      • 2020-10-09
      • 1970-01-01
      • 2015-05-27
      • 2022-01-26
      • 2017-04-30
      • 1970-01-01
      相关资源
      最近更新 更多