10

Fortran 2008do concurrentコンストラクトは、反復が他の反復に影響しないことをコンパイラーに伝える do ループです。したがって、安全に並列化できます。

有効な例:

program main
  implicit none
  integer :: i
  integer, dimension(10) :: array
  do concurrent( i= 1: 10)
    array(i) = i
  end do
end program main

反復は任意の順序で実行できます。詳細については、こちらをご覧ください。

私の知る限り、gfortran はこれらのdo concurrentループを自動的に並列化しませんが、gfortran-diffusion-list のメールでそれを実行したことを覚えています ( here )。それらを古典的なdoループに変換するだけです。

私の質問:ループを体系的に並列化する方法を知っていますか? do concurrentたとえば、体系的なopenmp 構文では?

4

2 に答える 2

14

自動的に行うのはそれほど簡単ではありません。DO CONCURRENTコンストラクトにはforall-headerがあります。これは、複数のループ、インデックス変数の定義、およびマスクを受け入れることができることを意味します。基本的に、次のものを交換する必要があります。

DO CONCURRENT([<type-spec> :: ]<forall-triplet-spec 1>, <forall-triplet-spec 2>, ...[, <scalar-mask-expression>])
  <block>
END DO

と:

[BLOCK
    <type-spec> :: <indexes>]

!$omp parallel do
DO <forall-triplet-spec 1>
  DO <forall-triplet-spec 2>
    ...
    [IF (<scalar-mask-expression>) THEN]
      <block>
    [END IF]
    ...
  END DO
END DO
!$omp end parallel do

[END BLOCK]

(角括弧内のものは、 forall-header内の対応するパーツの存在に基づいて、オプションです)

<iters 1>*<iters 2>*...これは、1つの大きなループを独立した反復で並列化するほど効果的ではないことに注意してください。これは、DO CONCURRENT期待されることです。forall-headerは、ヘッダー内でループインデックスを定義できるtype-specを許可していることにも注意してくださいBLOCK ... END BLOCK。セマンティクスを保持するには、構成内で全体を囲む必要があります。また、 forall-headerの最後にscalar-mask-exprが存在するかどうかを確認する必要があります。存在する場合は、それを最も内側のループ内に配置する必要があります。IF ... END IF

本体内に配列の割り当てしかない場合は、それをOpenMPディレクティブDO CONCURRENTに変換してFORALL使用することもできます。workshare上記よりもはるかに簡単です。

DO CONCURRENT <forall-header>
  <block>
END DO

次のようになります:

!$omp parallel workshare
FORALL <forall-header>
  <block>
END FORALL
!$omp end parallel workshare

上記のすべてを考えると、私が考えることができる唯一の体系的な方法は、ソースコードを体系的に調べ、forall-headerとループ本体のコンテンツに基づいて上記の変換された構造の1つを検索し体系的に置き換えることDO CONCURRENTです

編集: OpenMPworkshareディレクティブの使用は現在推奨されていません。少なくともIntelFortranコンパイラとGCCは、コンパイル中にOpenMPディレクティブでそれらを囲むことにより、FORALLOpenMPディレクティブ内のステートメントとコンストラクトをシリアル化し、スピードアップをまったくもたらさないことがわかりました。他のコンパイラはそれを異なる方法で実装するかもしれませんが、移植可能なパフォーマンスを達成するためには、その使用を避ける方が良いでしょう。worksharesingle

于 2012-07-19T08:52:03.947 に答える
2

「並行ループを体系的に並列化する方法」という意味がわかりません。ただし、通常のdoループを OpenMP で単純に並列化するには、次のようなものを使用できます。

!$omp parallel private (i)
!$omp do
do i = 1,10
    array(i) = i
end do
!$omp end do
!$omp end parallel

これはあなたが求めているものですか?

于 2012-07-18T21:43:44.413 に答える