0

Fortran でこのシーケンシャル コードを使用しています。私の問題は、Openmp ディレクティブを配置すると、並列化されたコードが順次コードよりも遅くなり、エラーが表示されないことです。

REAL, DIMENSION(:), ALLOCATABLE :: current, next
ALLOCATE ( current(TOTAL_Z), next(TOTAL_Z))

CALL CPU_TIME(t1)

!$OMP PARALLEL SHARED (current, next) PRIVATE (z)
DO t = 1, TOTAL_TIME
    !$OMP  DO SCHEDULE(STATIC, 2)
    DO z = 2, (TOTAL_Z - 1)
        next(z) = current (z) + KAPPA*DELTA_T*((current(z - 1) - 2.0*current(z) +      current(z + 1)) / DELTA_Z**2)
    END DO
    !$OMP END DO
    current = next
END DO

CALL CPU_TIME(t2)

!$OMP END PARALLEL 

TOTAL_Z、TOTAL_TIME、KAPPA、DELTA_T、DELTA_Z は定数です。
並列コードを実行すると、htop に表示され、2 つのコアが 100% で動作してい
ます。シーケンシャル コードでは、CPU_TIME は 79 セグメントで、並列コードでは 132 セグメントです
ありがとう

4

3 に答える 3

3

私はちょうど同じ問題を経験しています。

cpu_time() の使用は、マルチスレッド コードのパフォーマンスを測定するのには適していないようです。cpu_time() は、スレッド数の増加に伴い増加する可能性があるすべてのスレッドの合計時間を追加します。

別のフォーラムでこれを見つけました http://software.intel.com/en-us/forums/topic/281897

ルーチンのより正確なタイミングを取得するには、system_clock() または omp_get_wtime() 関数を使用する必要があります。

于 2013-09-30T14:24:29.713 に答える
1

反復回数によっては、ネスト配列での false-sharing の問題に直面している可能性もあります。DO ループの分散用のチャンク サイズはかなり小さいため、ネスト(z)、ネスト(z+1)、ネスト(z+2)、ネスト(z+3) などのキャッシュ ラインが次の間でスラッシングする可能性があります。 CPU の L1/L2 キャッシュ。

乾杯 - マイケル

于 2013-09-30T20:00:07.517 に答える
1

sharedスレッドが変数にアクセスするために競合しているため、おそらく遅いです。使用するように変更できる場合はreduction、より高速になる可能性があります。しかし、「現在」の計算は複数の配列要素にアクセスするため、これは簡単ではないかもしれません。

于 2013-03-12T15:11:30.577 に答える