Loops OPENMP F90/95嵌套DO循环-与串行实现相比问题得到改进

Loops OPENMP F90/95嵌套DO循环-与串行实现相比问题得到改进,loops,fortran,openmp,Loops,Fortran,Openmp,我已经做了一些搜索,但找不到任何似乎与我的问题相关的内容(如果我的问题是多余的,很抱歉!)。无论如何,正如标题所述,我很难在代码的串行实现上获得任何改进。我需要并行化的代码片段如下(这是带有OpenMP的Fortran90): 我是否遇到了比赛条件问题?还是我只是把指令放错地方了?我对这一点很陌生,所以如果这是一个过于简单化的问题,我道歉 无论如何,如果没有并行化,代码的速度会非常慢。为了了解问题的大小,lm、jm和im索引分别为60、401和501。因此,并行化至关重要。任何帮助或链接到有用的

我已经做了一些搜索,但找不到任何似乎与我的问题相关的内容(如果我的问题是多余的,很抱歉!)。无论如何,正如标题所述,我很难在代码的串行实现上获得任何改进。我需要并行化的代码片段如下(这是带有OpenMP的Fortran90):

我是否遇到了比赛条件问题?还是我只是把指令放错地方了?我对这一点很陌生,所以如果这是一个过于简单化的问题,我道歉

无论如何,如果没有并行化,代码的速度会非常慢。为了了解问题的大小,lm、jm和im索引分别为60、401和501。因此,并行化至关重要。任何帮助或链接到有用的资源将非常感谢!如果有用的话,我将使用xlf编译上述代码

谢谢!
-Jen

放置omp pragma的明显位置是最外面的循环

对于每一个(l,m,n),你在计算扰动变量和指数平滑器之间的卷积。每个(l,m,n)计算都是完全独立的,因此可以将其放在最外层的循环中。举个例子,最简单的事情

!$omp parallel do private(n,m,l,i,j,k,exp_smoother) shared(sum_u_pert,sum_v_pert,sum_t_pert,u_p,v_p,t_p), default(none)
do n=1,lm
  do m=1,jm
    do l=1,im
      do k=1,lm
        do j=1,jm
          do i=1,im
            exp_smoother=exp(-(abs(i-l)/hzscl)-(abs(j-m)/hzscl)-(abs(k-n)/vscl))
            sum_u_pert(l,m,n) = sum_u_pert(l,m,n) + u_p(i,j,k) * exp_smoother
            sum_v_pert(l,m,n) = sum_v_pert(l,m,n) + v_p(i,j,k) * exp_smoother
            sum_t_pert(l,m,n) = sum_t_pert(l,m,n) + t_p(i,j,k) * exp_smoother
          end do
        end do
      end do
    end do
  end do
end do
在8个内核上给了我~6倍的加速(使用了大大减少的20x41x41问题大小)。考虑到循环中要做的工作量,即使是较小的循环,我认为它不是8倍加速的原因涉及内存争用或错误共享;对于进一步的性能调优,您可能希望显式地将sum数组分解为每个线程的子块,并在最后合并它们;但是,根据问题的大小,可能不需要额外的im x jm x lm大小的阵列


这个问题似乎有很多结构,你无法通过爆炸来加速连环案件,但是说起来容易,然后找到它;在纸和笔上玩耍几分钟内什么都不会浮现在脑海中,但聪明的人可能会发现一些东西。

你所拥有的是一个卷积。这可以在N log2(N)时间内通过快速傅里叶变换完成。您的算法是N^2。如果您使用FFT,一个内核可能就足够了

谢谢!这很有帮助。我现在正在尝试一下。不幸的是,我还有一段路要走,才能达到我所需要的性能水平。我可以访问一台相当大的机器(每个处理器64个核)-但也许我需要将其与MPI结合起来以获得必要的性能。MPI的缺点可能是一些阵列的额外副本,但计算是如此独立,因此,如果跨MPI的分解对问题的其余部分有意义,这应该很容易。xlf+64核==电力系统?确保您使用的是-O5、-qhot和适当的-qarch标志,让编译器在这一点上真正发挥作用。由于有64个内核,最外层的循环只有约60次迭代,您可能会发现在omp do行中添加一个collapse(2)或collapse(3)子句是有利的。您在电力系统方面的投资是正确的。除了编译器标志之外,我明天还将尝试使用collapse子句。我还意识到,在整个网格中进行计算是没有必要的(对于我的问题),因此这也应该大大加快速度。再次感谢!我不知道堆栈溢出是如此巨大的资源!
!$omp parallel do private(n,m,l,i,j,k,exp_smoother) shared(sum_u_pert,sum_v_pert,sum_t_pert,u_p,v_p,t_p), default(none)
do n=1,lm
  do m=1,jm
    do l=1,im
      do k=1,lm
        do j=1,jm
          do i=1,im
            exp_smoother=exp(-(abs(i-l)/hzscl)-(abs(j-m)/hzscl)-(abs(k-n)/vscl))
            sum_u_pert(l,m,n) = sum_u_pert(l,m,n) + u_p(i,j,k) * exp_smoother
            sum_v_pert(l,m,n) = sum_v_pert(l,m,n) + v_p(i,j,k) * exp_smoother
            sum_t_pert(l,m,n) = sum_t_pert(l,m,n) + t_p(i,j,k) * exp_smoother
          end do
        end do
      end do
    end do
  end do
end do