インテル® Advisor ユーザーガイド
ここでは、OpenMP* atomic 操作の高度な用法について説明します。
高度な atomic 操作は atomic 構文の後に指定する read、write、update、capture および seq_cst 節によって行われます。atomic の節の引数を省略した場合、デフォルトでは update 節が適用されます。
これらの節は、OpenMP* 3.1 と 4.0 仕様に含まれるため、これらの高度な atomic 節をサポートしているインテル® C++ コンパイラー・クラシックまたはインテル® Fortran コンパイラー・クラシックが必要です。
次の C/C++ の例は、read と write 節を個別に使用しています。
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 の例は、read と write 節を個別に使用しています。
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
次の 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 節の例は、次のコードを使用するように変更できます。
// "アトミックスワップ" により、次のように記述できます。 newPos = foo(); . . . #pragma omp atomic capture { tmpPos = pos; pos = newPos; }