0

コードの並列部分に注目すると、以下に示すオプションのどれが優先されますか? より良い解決策はありますか?私は独立した実現の平均を作ろうとしていますdo_something

オプション 1: CRITICAL の使用

  resultado%uno = 0.d0
  !$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
  do i_omp=1, nthreads
     call do_something(large, resultadoOmp(i_omp))
     !$OMP CRITICAL (forceloop)
     resultado%uno = resultado%uno + resultadoOmp(i_omp)%uno
     !$OMP END CRITICAL (forceloop)
  enddo
  !$OMP END PARALLEL DO
  resultado%uno  = resultado%uno/nthreads

オプション 2: 回避CRITICAL(およびATOMIC)

  !$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
  do i_omp=1, nthreads
     call do_something(large, resultadoOmp(i_omp))
  enddo
  !$OMP END PARALLEL DO

  uno = 0.d0
  !$OMP PARALLEL DO shared(resultado) private(i_omp) schedule(static,1) &
  !$OMP & REDUCTION(+:uno)
  do i_omp=1, nthreads
     uno = uno + resultadoOmp(i_omp)%uno
  end do
  !$OMP END PARALLEL DO
  resultado%uno  = uno/nthreads

この点では、使用できませんでしREDUCTION(+:resultado%uno)REDUCTION(+:resultado)。数値型のみが許可されています。

この方法 (IMO) の欠点は、resultadoOmpスレッドの数を使用して派生チップの寸法を決める必要があることです。利点はCRITICAL、パフォーマンスに影響を与える可能性のある句を回避できることです。そうですか?

4

1 に答える 1

0

このアプローチ (IMO) の欠点は、派生したタイプ resultadoOmp にスレッド数を指定する必要があることです。利点は、パフォーマンスに影響を与える可能性のある CRITICAL 句を回避できることです。そうですか?

はい、あなたは正しいです。とにかくresultadoOmpをスレッド数で寸法付けているように見えるので、実際には不利ではありませんか?パフォーマンスは確かに 2 番目の部分の方が優れているはずですが、2 つの並列領域がこの利点を再び食いつぶす可能性があります。したがって、両方の部分に 1 つの並列領域のみを使用する必要があります。do_something の実行時間によっては、リダクション操作の並列処理を完全に無視して、すべての uno エントリを並列に計算した後、単一のスレッドで合計を実行することさえできます。

!$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
do i_omp=1, nthreads
   call do_something(large, resultadoOmp(i_omp))
end do
!$OMP END PARALLEL DO

resultado%uno = sum(resultadoOmp(:)%uno)/nthreads

結論を出すには、実際のセットアップでさまざまな実装を測定する必要があります。

于 2013-02-03T19:50:24.920 に答える