C语言 将顺序代码转换为 openMP 并行结构



我有以下一段代码,我想用openmp编写。

我的代码抽象地如下所示

我首先在p=10块之间平均划分N=100迭代,并将每个片段的分配迭代存储在向量中

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

这其实很简单 - 只需将外部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=0j=1

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

相关内容

  • 没有找到相关文章

最新更新