3

( atomic (9) のマニュアル ページに記載されているように) BSD が提供するアトミック操作には、 と がatomic_load_acq_int()ありatomic_store_rel_int()ます。他の OS で同等のものを探す場合 (たとえば、Mac OS X の atomic (3) マニュアル ページ、Solaris のatomic_ops ( 3C) マニュアル ページ、およびInterlocked*()Windows の関数を読むことによって) は、ないようです。をアトミックに読み書きするための(明らかな)同等物int

intこれは、読み取り/書き込みがデフォルトでアトミックであることが保証されている OS に対して暗示されているためですか? volatile(または、C/C++ でそれらを宣言する必要がありますか?)

そうでない場合、intそれらの OS でアトミックな読み取り/書き込みを行うにはどうすればよいですか?

(アトミック読み取りは、0 のアトミック加算の結果を返すことでシミュレートできますが、アトミック書き込みを行うのと同等のものはありません。)

4

1 に答える 1

4

アトミック メモリ アクセスキャッシュ コヒーレンスが混在していると思います。前者は、ソフトウェアで同期プリミティブ (スピンロック、セマフォ、およびミューテックス) を構築するために必要なハードウェア サポートであり、後者は、同じバス上で動作する複数のチップ (複数の CPU および周辺デバイス) のハードウェア サポートであり、メインメモリの一貫したビュー。

異なるコンパイラ/ライブラリは、最初に異なるユーティリティを提供します。たとえば、アトミック メモリ アクセス用の GCC 組み込み関数を次に示します。それらはすべて、プラットフォームのサポートに応じて、コンペアアンドスワップまたはロードリンク/ストア条件ベースの命令ブロックの生成に要約されます。-SたとえばGCC 用にソースをコンパイルし、生成されたアセンブラを確認します。

キャッシュの一貫性のために明示的に何かを行う必要はありません。すべてハードウェアで処理されます

以上のことから、アライメントされた単一ワードの読み取りと書き込みは、すべてのコモディティ プラットフォームでアトミックです (ここで間違っている場合は誰かが訂正してください)。s はサイズがプロセッサ ワード以下であるためint、カバーされます (上記の GCC ビルトイン リンクを参照してください)。

重要なのは読み取りと書き込みの順序です。ここで、アーキテクチャ メモリ モデルが重要になります。ハードウェアによって並べ替え可能な操作と並べ替えできない操作を指定します。例は、リンクされたリストの更新です。項目自体が一貫した状態になるまで、リンクされた新しい項目を他の CPU に表示させたくない場合です。明示的なメモリ バリア(「メモリ フェンス」とも呼ばれます) が必要になる場合があります。バリアを取得すると、バリアの前で後続の操作が並べ替えられないことが保証されます (たとえば、アイテムのコンテンツの前にリンクされたリストのアイテム ポインターを読み取るとします)。リリースバリアは、バリアの後に前の操作が並べ替えられないことを保証します (新しいリンク ポインターを書き込む前に、アイテムのコンテンツ)。

volatile上記のすべてに関連していると誤解されることがよくあります。実際、変数値をレジスターにキャッシュするのではなく、アクセスごとにメモリーから読み取るようにコンパイラーに指示するだけです。多くの人は、並行プログラミングには「ほとんど役に立たない」と主張しています。

返信が長くなってしまい申し訳ありません。これで少しすっきりすることを願っています。

編集:

今後の C++0x 標準は、最終的に並行性に対処します。多くの詳細については、 Hans Boehm の C++ メモリ モデルに関する論文を参照してください。

于 2010-07-11T16:50:46.303 に答える