アトミック メモリ アクセスとキャッシュ コヒーレンスが混在していると思います。前者は、ソフトウェアで同期プリミティブ (スピンロック、セマフォ、およびミューテックス) を構築するために必要なハードウェア サポートであり、後者は、同じバス上で動作する複数のチップ (複数の CPU および周辺デバイス) のハードウェア サポートであり、メインメモリの一貫したビュー。
異なるコンパイラ/ライブラリは、最初に異なるユーティリティを提供します。たとえば、アトミック メモリ アクセス用の GCC 組み込み関数を次に示します。それらはすべて、プラットフォームのサポートに応じて、コンペアアンドスワップまたはロードリンク/ストア条件ベースの命令ブロックの生成に要約されます。-S
たとえばGCC 用にソースをコンパイルし、生成されたアセンブラを確認します。
キャッシュの一貫性のために明示的に何かを行う必要はありません。すべてハードウェアで処理されます。
以上のことから、アライメントされた単一ワードの読み取りと書き込みは、すべてのコモディティ プラットフォームでアトミックです (ここで間違っている場合は誰かが訂正してください)。s はサイズがプロセッサ ワード以下であるためint
、カバーされます (上記の GCC ビルトイン リンクを参照してください)。
重要なのは読み取りと書き込みの順序です。ここで、アーキテクチャ メモリ モデルが重要になります。ハードウェアによって並べ替え可能な操作と並べ替えできない操作を指定します。例は、リンクされたリストの更新です。項目自体が一貫した状態になるまで、リンクされた新しい項目を他の CPU に表示させたくない場合です。明示的なメモリ バリア(「メモリ フェンス」とも呼ばれます) が必要になる場合があります。バリアを取得すると、バリアの前で後続の操作が並べ替えられないことが保証されます (たとえば、アイテムのコンテンツの前にリンクされたリストのアイテム ポインターを読み取るとします)。リリースバリアは、バリアの後に前の操作が並べ替えられないことを保証します (新しいリンク ポインターを書き込む前に、アイテムのコンテンツ)。
volatile
上記のすべてに関連していると誤解されることがよくあります。実際、変数値をレジスターにキャッシュするのではなく、アクセスごとにメモリーから読み取るようにコンパイラーに指示するだけです。多くの人は、並行プログラミングには「ほとんど役に立たない」と主張しています。
返信が長くなってしまい申し訳ありません。これで少しすっきりすることを願っています。
編集:
今後の C++0x 標準は、最終的に並行性に対処します。多くの詳細については、 Hans Boehm の C++ メモリ モデルに関する論文を参照してください。