メモリーの一貫性

IA-64 アーキテクチャーなど、"メモリーの一貫性が弱い" 一部のアーキテクチャーでは、効率化のためにハードウェアによって異なるアドレスでメモリー操作の順序が変更される場合があります。この複雑な動作については、資料 (Intel 2002, Robison 2003) をご覧ください。IA-32 アーキテクチャー・プラットフォームおよびインテル® 64 アーキテクチャー・プラットフォームのみでプログラミングを行う場合は、このセクションをスキップしても問題ありません。

順序の変更を制限するため、atomic<T> クラスは、次の表で説明されているように、メモリー操作を特定の順序で行います。

順序の制約

種類

説明

デフォルト

acquire (取得)

アトミック操作の後の操作はアトミック操作を決して越えません。

read (読み取り)

release (解放)

アトミック操作の前の操作はアトミック操作を決して越えません。

write (書き込み)

連続して一貫

アトミック操作の両側の操作はアトミック操作を決して越えません。連続して一貫したアトミック操作はグローバルな順序になります。

fetch_and_store

fetch_and_add

compare_and_swap

デフォルト列は、デフォルト操作を示します。予期しない問題を回避するために、デフォルトを使用してください。読み取り/書き込みの場合、デフォルトは利用可能な制約のみです。ただし、弱いメモリーの一貫性に精通している場合は、3 番目のデフォルトをより弱い操作に変更することもできます。この処理には、テンプレート引数を使用するバージョンを使用します。引数は acquire または release で、enum type 型の memory_semantics の値です。

例えば、さまざまなスレッドがデータ構造体の要素を生成し、データ構造が準備できたときに消費スレッドにシグナルを発信させるとします。これを行う 1 つの方法は、ビジーな生産スレッドの数でアトミックカウンターを初期化し、生産スレッドが終了したら、次の操作を行ってカウントをデクリメントする方法です。

refcount.fetch_and_add<release>(-1);

引数 release は、refcount がデクリメントされる前に生産スレッドの作業 (共有メモリーへの書き込み) が行われることを保証します。同様に、消費スレッドが refcount をチェックするときは、そのデータ構造の読み取りが、refcount が 0 になるのを見届けた後で行えるように、acquire フェンス (読み取りのデフォルト) を使用しなければなりません。