【问题标题】:Trouble parallelizing OpenACC loop无法并行化 OpenACC 循环
【发布时间】:2014-01-31 19:51:53
【问题描述】:

我有一个用 FORTRAN 编写的旧代码,我需要使用 OpenACC 对其进行加速,但是当我尝试使用指令时,它说存在 un,vn,pn 的依赖性,这会阻止并行性。是否可以并行化此循环?我是 OpenACC 的新手,但已与 OpenMP 并行处理

    !$acc parallel loop
    do 9000 j=2,jmaxm
    jm=j-1 
    jp=j+1

    do 9001 i=2,imaxm
    im=i-1
    ip=i+1

    if(rmask(i,j).eq.1.0) then


   ! Calculate un field

un(i,j,kp)=un(i,j,km)+ tdt*rmask(i,j)*(
 +    txsav(i,j)*zn(nmm)/xpsi2(nmm)+ visch*zetun(i,j)
 +   -recdx*(pn(ip,j,k)-pn(i,j,k))-a*un(i,j,km)/cn(nmm)**2
 +   +0.25* fu(i,j)*(vn(i,j,k)+vn(ip,j,k)+vn(i,jm,k)+
 +    vn(ip,jm,k))
 +   -damp(i,j)*un(i,j,km)
 +   )

 c SBnd damper is not used
 cc     +   -(1./timkwd)*dampu(i,j)*un(i,j,km)

 ! Calculate vn field

    vn(i,j,kp)=vn(i,j,km)+ tdt*rmask(i,j)*(
 +    tysav(i,j)*zn(nmm)/xpsi2(nmm)+visch*zetvn(i,j)
 +   -recdy*(pn(i,jp,k)-pn(i,j,k))-a*vn(i,j,km)/cn(nmm)**2
 +   -0.25*fv(i,j)*(un(im,jp,k)+un(i,jp,k)+un(im,j,k)+
 +    un(i,j,k))
 +   )

 c EBnd damper is not used
 cc     +   -(1./timkwd)*dampv(i,j)*vn(i,j,km)

 ! Calculate pn field

    pn(i,j,kp)=pn(i,j,km)+tdt*rmask(i,j)*(
 +    cn(nmm)**2*(
 +   -recdx*(un(i,j,k)-un(im,j,k))
 +   -recdy*(vn(i,j,k)-vn(i,jm,k)))
 +   -a*pn(i,j,k)/cn(nmm)**2
 +   -dampu(i,j)*cn(nmm)/dx*pn(i,j,km)
 +   -dampv(i,j)*cn(nmm)/dx*pn(i,j,km)
 +   -damp(i,j)*pn(i,j,km)
 +   )

    rhon(i,j)=-pn(i,j,kp)/g
    wn(i,j)=
 +   -recdx*(un(i,j,kp)-un(im,j,kp))
 +   -recdy*(vn(i,j,kp)-vn(i,jm,kp))

    endif
 9001    continue
 9000    continue
 !$acc end parallel loop

【问题讨论】:

  • 问题是什么?它到底说了什么?
  • 您的循环似乎在迭代之间存在一些复杂的依赖关系。您可以尝试使用 independent 关键字强制编译器生成内核并忽略依赖项检测,但这可能会产生顺序内核。您使用的是什么编译器,您在哪里编写了编译指示?
  • 我需要知道是否可以使用 openacc 在 GPU 上运行循环
  • @Ruyk 我已在编辑后的代码中添加了编译指示。我已经尝试了 !$acc 部分和 !$acc 并行循环编译指示,在我的情况下两者的锻炼方式相同。我正在使用 PGI Fortran 工作站 2013。
  • 我认为这可能是可以并行化的,但是您还没有充分展示正在发生的事情。我猜k 的某个地方有一个循环,你没有显示。无论如何,你有循环携带的依赖关系,例如un 计算取决于其他相邻的un 数量(例如un(i,j,km)),编译器会对此感到窒息。一种方法是有两个 un 数组,例如ununn,并在它们之间进行乒乓球计算,即unn(i,j,kp)=un(i,j,km+ tdt... 等。另外,我通常会先尝试!$acc kernels,然后再尝试其他方法。

标签: fortran gpgpu openacc


【解决方案1】:

您具有数据依赖性,这意味着您的算法本质上是顺序的,

一个简单的例子是 Gauss-Seidel 和 Jacobi 迭代之间的区别,以及为什么人们在 GPU 中使用 Jacobi 而不是 Gaus Seidel,

【讨论】:

  • 你可以有红黑高斯赛德尔。
  • 当然,我只是想指出差异,如果你也想的话,你也可以使用 GMRES :-),sasiba
猜你喜欢
  • 2015-11-18
  • 2020-10-02
  • 2015-10-22
  • 2020-08-14
  • 2018-09-23
  • 2020-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多