OpenMP迭代for循环并行区域

Poc*_*chi 5 c c++ parallel-processing openmp

对不起,如果标题是一个很大的不清楚.我不太清楚怎么说这个.

我想知道我是否有办法做到以下几点:

#pragma omp parallel
{
    for (int i = 0; i < iterations; i++) {
        #pragma omp for
        for (int j = 0; j < N; j++)
            // Do something
    }
}
Run Code Online (Sandbox Code Playgroud)

忽略诸如在for循环中省略私有说明符之类的东西,有什么方法可以在我的外部循环之外分叉线程,这样我就可以并行化内部循环?根据我的理解(如果我错了请纠正我),所有线程都将执行外部循环.我不确定内循环的行为,但我认为for会将块分配给遇到它的每个线程.

我想要做的是不必fork/join iterations次,而只需在外循环中执行一次.这是正确的策略吗?

如果有另一个外环不应该并行化怎么办?那是...

#pragma omp parallel
{

    for (int i = 0; i < iterations; i++) {
        for(int k = 0; k < innerIterations; k++) {
            #pragma omp for
            for (int j = 0; j < N; j++)
                // Do something

            // Do something else
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果有人向我指出使用OpenMP并行化的大型应用程序的示例,那将是很好的,这样我就可以更好地理解使用OpenMP时要采用的策略.我似乎找不到任何东西.

澄清:我正在寻找不会改变循环排序或涉及阻塞,缓存和一般性能考虑因素的解决方案.我想了解如何在OpenMP上对指定的循环结构进行此操作.在// Do something可能或不可能有依赖性,认为他们做的,你不能走动的东西.

小智 1

我不确定我能回答你的问题。我现在只使用 OpenMP 几个月,但当我尝试回答这样的问题时,我做了一些 hello world printf 测试,如下所示。我认为这可能有助于回答您的问题。也尝试#pragma omp for nowait看看会发生什么。

只要确保当您“//做某事和//做其他事”时,您不会写入相同的内存地址并创建竞争条件。另外,如果您正在进行大量读写操作,则需要考虑如何有效地使用缓存。

#include "stdio.h"
#include <omp.h>
void loop(const int iterations, const int N) {
    #pragma omp parallel
    {
        int start_thread = omp_get_thread_num();
        printf("start thread %d\n", start_thread);
        for (int i = 0; i < iterations; i++) {
            printf("\titeration %d, thread num %d\n", i, omp_get_thread_num());
            #pragma omp for
            for (int j = 0; j < N; j++) {
                printf("\t\t inner loop %d, thread num %d\n", j, omp_get_thread_num());
            }
        }
    }
}

int main() {
    loop(2,30);
}
Run Code Online (Sandbox Code Playgroud)

就性能而言,您可能需要考虑像这样融合循环。

#pragma omp for
for(int n=0; n<iterations*N; n++) {
    int i = n/N;
    int j = n%N;    
    //do something as function of index i and j
}
Run Code Online (Sandbox Code Playgroud)