高度な OpenMP* の atomic 操作

ここでは、OpenMP* *atomic 操作の高度な用法について説明します。

これらの高度な atomic 操作では、readwriteupdatecapture、および seq_cst などの atomic 構造の後で節を使用します。atomic の節の引数を省略した場合、デフォルトでは update 節が適用されます。

これらの節は、OpenMP* 3.1 と 4.0 仕様に含まれるため、これらの高度な atomic 節をサポートしているインテル® Fortran コンパイラー・クラッシックなどが必要です。

ヒント

OpenMP* 並列フレームワークを使用してコードを書き直した後、インテル® Advisor でパフォーマンスを解析できます。Vectorization and Code Insights (ベクトル化とコードの調査) パースペクティブを使用して、OpenMP* コードがどの程度ベクトル化されているか解析するか、Offload Modeling (オフロードのモデル化) パースペクティブで GPU でのパフォーマンスをモデル化できます。

readwrite 節の使用例

次の C/C++ の例は、readwrite 節を個別に使用しています。

int atomic_read(const int *x) 
{ 
     int value; 
     /* *x の値全体をアトミックに読み取ります。 *//* 読み取り操作中に *x は変更されません。 */
#pragma omp atomic read 
     value = *x; 
     return value; 
} 
void atomic_write(int *x, int value) 
{ 
     /* 値を *x にアトミックに保存します。 */   
     /* 書き込み操作全体が完了するまで、*x は変更されません。 */
#pragma omp atomic write 
     *x = value; 
}

次の Fortran の例では、readwrite 節を使用します。

function atomic_read(x) 
     integer :: atomic_read 
     integer, intent(in) :: x   ! x の値が全体でアトミックに読み取られることを指示します。
                                ! 読み取り操作中に x は変更されません。

!$omp atomic read 
     atomic_read = x 
     return 
end function atomic_read 
subroutine atomic_write(x, value) 
     integer, intent(out) :: x 
     integer, intent(in) :: value    ! 値はアトミックに x に保存されることを指示します。
                                     ! 書き込み操作全体が完了するまで、x は変更されません。
  !$omp atomic write 
     x = value 
end subroutine atomic_write

基本的な capture 節の使用例

次の C/C++ の例では、capture 節を使用しています。

#pragma omp parallel for shared (pos) 
     for (int i=0; i < size; i++) { 
          if (isValid(data[i])) { 
               int tmpPos; 
               // omp atomic capture プラグマを使用 
               #pragma omp atomic capture 
               { 
                    tmpPos = pos; 
                    pos = pos+1; 
               }  
               // すべての選択した要素のインデックスを index にパックします 
               // (インデックス値の順番は重要ではありません)。 
               index[tmpPos] = i;
          } 
     }
                index[tmpPos] = i;
          }
     }

capture 節のスワップ形式を使用した例

上記の capture 節の例は、次のコードを使用するように変更できます。

//  "atomic スワップ" により、次のように記述できます: 
       newPos = foo();
       .
       .
       .
#pragma omp atomic capture 
          { 
               tmpPos = pos; 
               pos = newPos; 
          }

関連情報