私はこれとこれを認識していますが、最初のリンクは現在かなり古く、2番目のリンクは決定的な答えに達していないようです. コンセンサスは形成されましたか?
私の問題は簡単です:
同時に実行できる要素DO
を持つループがあります。どの方法を使用しますか?
以下は、単純な立方格子上に粒子を生成するコードです。
- npartは粒子の数です
- npart_edgeとnpart_faceは、それぞれエッジと面に沿ったものです
- spaceは格子間隔
- Rx、Ry、Rzは位置配列です
- x、y、zは、格子上の位置を決定するための一時的な変数です
x、y、z は、CONCURRENT の場合は配列でなければならないが、OpenMP の場合は PRIVATE として定義できるため、そうではないという違いに注意してください。
だから私は使用しますかDO CONCURRENT
(上記のリンクからわかるように、SIMDを使用します):
DO CONCURRENT (i = 1, npart)
x(i) = MODULO(i-1, npart_edge)
Rx(i) = space*x(i)
y(i) = MODULO( ( (i-1) / npart_edge ), npart_edge)
Ry(i) = space*y(i)
z(i) = (i-1) / npart_face
Rz(i) = space*z(i)
END DO
または、OpenMP を使用しますか?
!$OMP PARALLEL DEFAULT(SHARED) PRIVATE(x,y,z)
!$OMP DO
DO i = 1, npart
x = MODULO(i-1, npart_edge)
Rx(i) = space*x
y = MODULO( ( (i-1) / npart_edge ), npart_edge)
Ry(i) = space*y
z = (i-1) / npart_face
Rz(i) = space*z
END DO
!$OMP END DO
!$OMP END PARALLEL
私のテスト:
サイド 10 のボックスに 64 個のパーティクルを配置する:
$ ifort -qopenmp -real-size 64 omp.f90
$ ./a.out
CPU time = 6.870000000000001E-003
Real time = 3.600000000000000E-003
$ ifort -real-size 64 concurrent.f90
$ ./a.out
CPU time = 6.699999999999979E-005
Real time = 0.000000000000000E+000
サイド 100 のボックスに 100000 個のパーティクルを配置する:
$ ifort -qopenmp -real-size 64 omp.f90
$ ./a.out
CPU time = 8.213300000000000E-002
Real time = 1.280000000000000E-002
$ ifort -real-size 64 concurrent.f90
$ ./a.out
CPU time = 2.385000000000000E-003
Real time = 2.400000000000000E-003
コンストラクトを使用するDO CONCURRENT
と、少なくとも 1 桁はパフォーマンスが向上するようです。これは i7-4790K で行われました。また、同時実行の利点は、サイズが大きくなるにつれて減少するようです。