Fortran 在OpenMP中并行化此循环的最佳方法

Fortran 在OpenMP中并行化此循环的最佳方法,fortran,openmp,fortran77,Fortran,Openmp,Fortran77,我有以下循环,我尝试使用OpenMP并行化,但我没有看到性能改进,请任何人建议如何改进它 thread = omp_get_max_threads ( ) chunk=jmaxm/thread c$omp parallel shared (zetun,zetvn) private (i, j) c$omp do schedule(DYNAMIC,chunk) ORDERED do j=2,jmaxm jm=j-1 jp=j+1 d

我有以下循环,我尝试使用OpenMP并行化,但我没有看到性能改进,请任何人建议如何改进它

thread = omp_get_max_threads ( )
chunk=jmaxm/thread
c$omp parallel shared (zetun,zetvn) private (i, j)
c$omp do schedule(DYNAMIC,chunk) ORDERED
    do j=2,jmaxm
        jm=j-1
        jp=j+1
             do i=2,imaxm
                if (rmask(i,j).eq.1.0)then
             im=i-1
             ip=i+1
             zetun(i,j)=
           +  (un(im,j,km)+un(ip,j,km)-2.*un(i,j,km))*recdx2
           +  + ((un(i,jp,km)-un(i,j,km))-
           +  (un(i,j,km)-un(i,jm,km)))*recdy2

             zetvn(i,j)=
           +  ((vn(ip,j,km)-vn(i,j,km))-
           +  (vn(i,j,km)-vn(im,j,km)))*recdx2
           +  + (vn(i,jp,km)+vn(i,jm,km)-2.*vn(i,j,km))*recdy2
              endif

        end do

    end do
 c$omp end do nowait
 c$omp end parallel
我现在添加修改后的代码,如下所示,但似乎仍然没有任何改进 修改代码:

  c$omp parallel shared (zetun,zetvn) private (i,j,jm,jp,im,ip,km)

  c$omp do schedule(DYNAMIC,20) 
   do j=2,jmaxm
        jm=j-1
        jp=j+1
             do i=2,imaxm
                if (rmask(i,j).eq.1.0)then
             im=i-1
             ip=i+1
             zetun(i,j)=
           +  (un(im,j,km)+un(ip,j,km)-2.*un(i,j,km))*recdx2
           +  + ((un(i,jp,km)-un(i,j,km))-
           +  (un(i,j,km)-un(i,jm,km)))*recdy2

             zetvn(i,j)=
           +  ((vn(ip,j,km)-vn(i,j,km))-
           +  (vn(i,j,km)-vn(im,j,km)))*recdx2
           +  + (vn(i,jp,km)+vn(i,jm,km)-2.*vn(i,j,km))*recdy2
              endif

           end do

    end do
c$omp end do
c$omp end parallel

代码无效
jm
jp
im
ip
必须至少是私有的。另外,您为什么要求订购
?它肯定会减慢速度。还有,hhy
计划动态的
,有这么大的块吗?只需使用
静态


另外,在编码时,或者至少在向他人展示代码时,使用一些行缩进。

我如前所述做了,但现在需要更多的时间,那么现在需要使用nowait吗?@HighPerformanceMark是的,上面的代码相同,我确实添加了jm、jp、im和ip作为专用代码,但仍然是缓慢的,而且是动态变化的,块到静态由于最内部的计算被屏蔽,因此计算负载取决于
rmask
的内容,
static
可能不是最佳调度。但是对于这样的块大小,
dynamic
。@JoviDsilva,当存在一些计算不平衡时,
dynamic
调度有帮助。但在您的例子中,您将块大小设置为
#iterations/#threads
,这意味着每个线程获得相同大小的迭代块。对于默认块大小的
静态
调度也是如此。在没有任何调度规范的情况下,大多数OMP运行时默认为
静态
(尽管标准没有保证)。您仍然可以使用dynamic,但是使用更小的块大小,否则它几乎没有意义。选择正确的块大小有点棘手,可能需要进行实验。看在上帝的份上,请使用一些缩进!