将顺序代码转换为openMP并行构造

时间:2017-05-16 16:36:26

标签: c multithreading multiprocessing openmp

我想在openmp中编写以下代码。

我的代码抽象地看起来像下面的

我首先在N=100件中平均分配p=10次迭代,并将每个部件的已分配迭代存储在一个向量中

Nvec[1]={0,1,..,9}
Nvec[2]={10,11,..,19}
Nvec[p]={N-9,..,N}

然后我循环迭代

for(k=0;k<p;k++){\\loop on each piece of Nvec
    for(j=0;j<2;j++){\\here is a nested loop
        for(i=Nvec[k][0];i<Nvec[k][p];i++){
            \\then I loop between the first and 
            \\last value of the array corresponding to piece k
    }
}

现在,您可以看到代码是连续的,总共2*100=200 iterations,我希望使用OpenMp并行绝对条件来保持迭代顺序!

我尝试了以下

#pragma omp parallel for schedule(static) collapse(2)
{
for(j=0;j<2;j++){
    for(i=0;i<n;i++){
        \\loop code here
    }
}
}

此设置不会像顺序版本那样保持迭代的顺序。 在顺序版本中,每个块完全使用j=0处理,然后完全使用j=1处理。

在我的openMP版本中,每个线程都需要一大堆迭代,并使用j=0完全处理它。在某种程度上,所有主题都会处理j=0j=1个案例。每个p=10进程200/10=20 iterations的工作人员,问题是所有迭代都是j=0 or j=1

如何确保每个线程获得一大块迭代,在所有迭代上使用j=0执行循环代码,然后在同一块上执行j=1迭代?

修改

我想要的每个20次迭代的内容

worker 1
j:0
i:1--->10
j:1
i:1--->10
worker p
j:0
i:90--->99
j:1
i:90--->99

上面的openMP代码

worker 1
j:0
i:1--->20
worker p
j:1
i:80--->99

1 个答案:

答案 0 :(得分:1)

这实际上很简单 - 只需将外部j - 循环非工作共享:

#pragma omp parallel
for (int j = 0; j < 2; j++) {
    #pragma omp for schedule(static)
    for (int i = 0; i < 10; i++) {
         ...
    }
}

如果您使用static时间表,则OpenMP保证每个工作人员都可以为ij=0处理相同范围的j=1

注意:将parallel构造移动到外部循环只是一种优化,以避免线程管理开销。如果您只是在两个循环之间放置parallel for,代码的工作方式类似。