インテル® Advisor ユーザーガイド

高度な OpenMP* の atomic 操作

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

高度な atomic 操作は atomic 構文の後に指定する readwriteupdatecapture および seq_cst 節によって行われます。atomic の節の引数を省略した場合、デフォルトでは update 節が適用されます。

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

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;
          } 
     }

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

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

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

関連情報