インテル® C++ コンパイラー XE 13.1 ユーザー・リファレンス・ガイド

omp atomic

特定のメモリー位置をアトミックに更新し、複数のスレッドが同時に読み取り/書き込みを行う危険性を回避します。

構文

#pragma omp atomic [ read | write | update | capture ]

expression-stmt

OR

#pragma omp atomic capture

structured-block

引数

clause (節) は次のいずれかです。

read

expression-stmtv = x; 形式になります。

write

expression-stmtx = expr; 形式になります。

update (または指定しない場合)

expression-stmt は、次のいずれかの形式になります。

x++;

x--;

++x;

--x;

x binop= expr;

capture

expression-stmt は、次のいずれかの形式になります。

v = x++;

v = x--;

v = ++x;

v = --x;

v = x binop= expr;

または、structured-block を使用する場合は、次のいずれかの形式になります。

{v = x; x binop= expr}

{x binop= expr; v = x}

上記の式の説明:

  • xv (該当する場合) はともにスカラー型の l-value 式です。

  • アトミック領域の実行中、構文上の複数の x は同じメモリー位置を指定していなければなりません。

  • v または expr (該当する場合) のいずれも x で指定されたメモリー位置にアクセスしない可能性があります。

  • expr はスカラー型の式です。

  • binop は次のいずれかです: +、*、-、/、&、^、|、<<、または >>

  • binop、binop=++、および -- は多重定義演算子ではありません。

説明

アトミック領域のバインドスレッドは、すべてのスレッドです。アトミック領域は、プログラム中のすべてのスレッドがその所属チームに関係なく、複数のアトミック領域によってアクセスされる同じメモリー位置 x への排他アクセスを徹底します。

#pragma omp atomic には、「プログラム全体を通して、メモリー位置 x へのすべてのアトミックアクセスは、同じ型と型パラメーターでなければならない」という制限があります。

次の表は、atomic 構造でそれぞれの節を指定した場合の影響を説明したものです。

結果

read

ネイティブマシンのワードサイズに関係なく、メモリー位置 x へのアトミックな読み取りが行われます。

write

ネイティブマシンのワードサイズに関係なく、メモリー位置 x へのアトミックな書き込みが行われます。

[update]

指定された演算子または組込み関数を使用して、メモリー位置 x がアトミックに更新されます。 次の規則も適用されます。

  • メモリー位置 x の読み取りまたは書き込みを行うための expr または expr-list の評価は、アトミックで行う必要はありません。
  • メモリー位置 x の読み取りと書き込みの間にタスク・スケジューリング・ポイントはありません。

capture

指定された演算子または組込み関数でメモリー位置 x がアトミックに更新されます。また、アトミックな更新時に、メモリー位置 x の元の値または最後の値もキャプチャーされます。 次の規則も適用されます。

  • メモリー位置 x の元の値または最後の値は、通常の言語セマンティクスに従い、atomic 構造、構造ブロック、または文に基づいてメモリー位置 v に書き込まれます。
  • メモリー位置 x への読み取りと書き込みのみアトミックに行われます。
  • メモリー位置 x の読み取りまたは書き込みを行うための expr または expr-list の評価およびメモリー位置 v への書き込みは、アトミックで行う必要はありません。

メモリー位置 x の読み取りと書き込みの間にタスク・スケジューリング・ポイントはありません。

2 つ以上の atomic 構造を組み合わせることで、メモリー位置 x への排他アクセスを行うことができます。

同期処理をせずに 2 つのスレッドが同じ共有変数にアクセスし、少なくとも一方のスレッドがその変数を変更する場合、データ競合が発生し、予期しない結果を引き起こすことがあります。 競合を回避するには、メモリー位置 x へ並列にアクセスする可能性がある場合、atomic 構造を使用して該当するすべてのアクセスを保護する必要があります。

アトミック領域は、OpenMP* のロックが実行タスクによって保有されている間、または reduction 節の実行中は、critical 領域あるいは ordered 領域であっても、領域外の同じメモリー位置 x への排他アクセスを保証しません。

ただし、ほかの OpenMP* の同期を使用することで、排他アクセスを指定することができます。 例えば、x への一連のアトミックな更新の後に barrier プラグマを指定することで、それ以降のアクセスがアトミックアクセスと競合しないようにできます。

#pragma omp atomic update
     k += n*mass;		 // k is updated atomically

#pragma omp atomic read
     tmp = c;		//  c is read atomically 

#pragma omp atomic write
     count = n*m;		// count is written atomically

#pragma omp atomic capture
     { d = v; v += n; } // atomically update v, but capture original value of v in d

#pragma omp atomic capture
     { o = c++; }	    	// capture the old value of c, then increment c


このヘルプトピックについてのフィードバックを送信