Loops 用OpenMP并行化Fortran嵌套循环
我必须用OpenMP并行化Fortran中的一个程序子程序,该子程序匹配块结构网格中的面 想象一个被划分为Loops 用OpenMP并行化Fortran嵌套循环,loops,parallel-processing,fortran,match,openmp,Loops,Parallel Processing,Fortran,Match,Openmp,我必须用OpenMP并行化Fortran中的一个程序子程序,该子程序匹配块结构网格中的面 想象一个被划分为NBLKS块的域。每个块被划分为一定数量的单元-每个块的单元数量相同。 该子程序的目的是匹配每个块边界单元的每个面,以便程序知道我们正在谈论的是相邻单元和块 它有4个嵌套循环。第一个在块之间,然后在边界单元面之间-对于第一个循环中的给定块-然后在所有块和边界单元中查找相邻的面单元。当它找到它时,它会在数组中写入它的位置和坐标。 对于两个相邻块,有相邻单元,它们的相邻面实际上是相同的,因此当它
NBLKS
块的域。每个块被划分为一定数量的单元-每个块的单元数量相同。
该子程序的目的是匹配每个块边界单元的每个面,以便程序知道我们正在谈论的是相邻单元和块
它有4个嵌套循环。第一个在块之间,然后在边界单元面之间-对于第一个循环中的给定块-然后在所有块和边界单元中查找相邻的面单元。当它找到它时,它会在数组中写入它的位置和坐标。
对于两个相邻块,有相邻单元,它们的相邻面实际上是相同的,因此当它在块1中找到给定面的匹配时,当循环转到块2时,它不会查找任何内容,因为FLAGOC逻辑告诉给定ID面的匹配与否
我有以下问题:
- 当我将
私有化时,一个块不知道是否有任何面的匹配,因此它不需要工作FLAGOC
- 需要按顺序写入
和IJLPBK
数组,这样块1的面是第一个,块2的面是第二个,依此类推,但由于将不同的块分配给不同的线程,块4的面可能在块2的面之前IJRPBK
- 目前,使用串行程序的时间更长李>
subroutine intfind
c$omp parallel private ( iol, lr, ior, ll, id, nthrds, ijpl, ijpr, xyze, err)
c$omp& firstprivate(flagoc, lnomatch)
c$omp do schedule(static)
do ll=1,nblks
do iol=iocbk(ll)+1,iocbk(ll)+nocbk(ll)
if(flagoc(iol)) then
flagoc(iol)=.false.
ijpl=ijlpbm(iol)+ijkbk(ll)
do lr=ll,nblks
do ior=iocbk(lr)+1,iocbk(lr)+nocbk(lr)
if(flagoc(ior)) then
ijpr=ijlpbm(ior) +ijkbk(lr)
check if there is a match
if(err .eq. 0) then
flagoc(ior)=.false.
c$omp atomic
newoc=newoc+1
ijlpbk(newoc)=ijpl
ijrpbk(newoc)=ijpr
endif
endif
end do
end do
endif
end do
end do
c$omp end do
c$omp end parallel
return
end
你可能把代码剪得太多了,我们无法测试它,它是不完整的。看见考虑使用现代语法使它更可读(小标题,自由形式等等)。不一致的缩进没有帮助,你有
if
,然后下面有do
,从缩进中可以看到end if
。如果你真的想并行化,并获得良好的性能,我想你必须重新考虑上面所述的订购要求,排序和并行化通常是不兼容的。否则,我同意弗拉基米尔的观点,很难从你目前的情况中看出更多。