Loops 用OpenMP并行化Fortran嵌套循环

Loops 用OpenMP并行化Fortran嵌套循环,loops,parallel-processing,fortran,match,openmp,Loops,Parallel Processing,Fortran,Match,Openmp,我必须用OpenMP并行化Fortran中的一个程序子程序,该子程序匹配块结构网格中的面 想象一个被划分为NBLKS块的域。每个块被划分为一定数量的单元-每个块的单元数量相同。 该子程序的目的是匹配每个块边界单元的每个面,以便程序知道我们正在谈论的是相邻单元和块 它有4个嵌套循环。第一个在块之间,然后在边界单元面之间-对于第一个循环中的给定块-然后在所有块和边界单元中查找相邻的面单元。当它找到它时,它会在数组中写入它的位置和坐标。 对于两个相邻块,有相邻单元,它们的相邻面实际上是相同的,因此当它

我必须用OpenMP并行化Fortran中的一个程序子程序,该子程序匹配块结构网格中的面

想象一个被划分为
NBLKS
块的域。每个块被划分为一定数量的单元-每个块的单元数量相同。 该子程序的目的是匹配每个块边界单元的每个面,以便程序知道我们正在谈论的是相邻单元和块

它有4个嵌套循环。第一个在块之间,然后在边界单元面之间-对于第一个循环中的给定块-然后在所有块和边界单元中查找相邻的面单元。当它找到它时,它会在数组中写入它的位置和坐标。 对于两个相邻块,有相邻单元,它们的相邻面实际上是相同的,因此当它在块1中找到给定面的匹配时,当循环转到块2时,它不会查找任何内容,因为FLAGOC逻辑告诉给定ID面的匹配与否

我有以下问题:

  • 当我将
    FLAGOC
    私有化时,一个块不知道是否有任何面的匹配,因此它不需要工作
  • 需要按顺序写入
    IJLPBK
    IJRPBK
    数组,这样块1的面是第一个,块2的面是第二个,依此类推,但由于将不同的块分配给不同的线程,块4的面可能在块2的面之前
  • 目前,使用串行程序的时间更长
我删减了代码,使之更简单。面坐标实际上比这复杂得多,并且有很多mor变量。此外,如果未找到匹配项,则会打印警告

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
。如果你真的想并行化,并获得良好的性能,我想你必须重新考虑上面所述的订购要求,排序和并行化通常是不兼容的。否则,我同意弗拉基米尔的观点,很难从你目前的情况中看出更多。