私は OpenACC 計算流体力学コードに取り組んでおり、全体的な計算を一連の小さな操作に分割することで、ループ内の計算の粒度を高めています。私の最終的な目標は、GPU で元の複雑なタスクを小さく単純な一連のタスクに分割することで、脅威ごとのレジスタの量を減らすことです。
たとえば、計算ドメインの特定のノードに対して計算する数式が多数あります。
!$acc parallel loop ...
do i=1,n
D1 = s(i+1,1) - s(i-1,1)
D2 = s(i+1,2) - s(i-1,2)
...
R = D1 + D2 + ...
enddo
ご覧のとおり、計算をブロックのスレッドに分散し、最後に結果を (リダクションによって) R に合計できます。したがって、内部並列ループを次のように定義しました。
!$acc parallel loop
do i=1,n
!$acc parallel loop ...
do j=1,m
D[j] = s(i+1,j) - s(i-1,j)
end
!$acc parallel loop reduction(+:R)
do j=1,m
R = R + D[j]
enddo
enddo
ただし、D をすべてのスレッドの共有メモリとして定義する必要がありますが、OpenACC の最善の方法が実際にはわかりません。(!$acc キャッシュを使用しましたが、パフォーマンスが低下しました)。また、変更されていないデータを定数メモリに送信する必要がありますが、どうすればよいかわかりません。
このアイデアを OpenACC に実装する効率的な方法はありますか? 本当にありがとうございました。
どうもありがとう、ベザド