我有以下一段代码,我想用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=0
或j=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 保证每个工作线程将处理相同范围的i
j=0
和j=1
。
注意:将parallel
构造移动到外部循环只是为了避免线程管理开销的优化。如果只是在两个循环之间放置一个parallel for
,则代码的工作方式类似。