我想在 openmp 中编写以下代码。
我的代码抽象如下所示
我首先从除法N=100
开始p=10
之间的迭代次数相等件,我将每个件分配的迭代存储在 vector 中
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
}
}
}
此设置不会像顺序版本中那样保留迭代的顺序。
在顺序版本中,每个 block 都完全用 j=0
进行处理。然后完全使用 j=1
.
在我的 openMP 版本中,每个线程都会进行大量迭代并使用 j=0
完全处理它。 。在某种程度上,所有线程都会处理 j=0
或j=1
案例。每个 worker 都有p=10
流程200/10=20 iterations
,问题是所有迭代都是 j=0 or j=1
.
如何确保每个线程都获得一大块迭代,使用 j=0
执行循环代码在所有迭代中,则 j=1
在同一个迭代 block 上?
编辑
对于 20 次迭代的每一 block ,我到底想要什么
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
,则代码的工作方式类似。在两个循环之间。
关于c - 将顺序代码转换为 openMP 并行结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44007026/