[解決済み] C++のvolatileキーワードはメモリフェンスを導入するか?
質問
私は、以下のことを理解しています。
volatile
は値が変更される可能性があることを通知しますが、この機能を実現するために、コンパイラはメモリフェンスを導入する必要があるのでしょうか?
私の理解では、volatileオブジェクトに対する操作の順序を変更することはできず、保存する必要があります。これは、何らかのメモリ フェンスが必要であり、これを回避する方法は実際にはないことを示唆しているように思われます。私はこれを言って正しいのでしょうか?
に興味深い議論があります。 この関連する質問
<ブロッククオート... 別々の揮発性変数へのアクセスは、それらが別々の完全な式で発生する限り、コンパイラによって並べ替えられることはない。 コンパイラによって並べ替えられることはありません。 スレッドセーフのためにvolatileが役に立たないというのは正しいが、彼の言うような理由ではない しかし、彼の言うような理由ではありません。コンパイラがvolatileオブジェクトへのアクセスを並べ替える可能性があるからではなく へのアクセスを並べ替える可能性があるからではなく、CPUが並べ替える可能性があるからです。アトミック アトミック操作とメモリバリアによって、コンパイラとCPUは 並べ替えを防ぐ
に対して デビッド・シュワルツ 返信 コメント中 :
... C++標準の観点からすると、違いはありません。 コンパイラが何かをすることと、コンパイラが命令を出してハードウェアに何かをさせることの間に ハードウェアに何かをさせる命令であることに違いはありません。もしCPUが CPUが揮発性物質にアクセスする順番を変えても、標準はその順番を守ることを要求しない。 その順番を維持する必要はありません。...
... C++の標準では、何が順序を変更するのかについて区別していません。 を区別していません。そして、CPU は観察可能な影響を与えずに並べ替えられるから大丈夫、とは言えません。 C++標準では、順序は観測可能であると定義されています。 C++の標準では、順序は観察可能であると定義されています。コンパイラは、あるプラットフォームでC++規格に準拠している。 コンパイラは、あるプラットフォームでC++規格に準拠しています。 標準に準拠しています。もし、標準が揮発性物質にアクセスする際に順序を変えないことを要求しているならば 標準が揮発性物質へのアクセスが順番を変えないことを要求しているならば、順番を変えるプラットフォームは標準に準拠していない。...
私が言いたいのは、もし C++ 標準がコンパイラが異なる揮発性物質にアクセスすることを禁止しているならば という理論に基づいて、異なる揮発性物質へのアクセスの順序を変更することを禁止しているということです。 そのようなアクセスの順序は、プログラムの観察可能な動作の一部であるという理論に基づいています。 CPUがそうすることを禁止するコードをコンパイラが出力することも要求しています。 を禁止するコードを出すことも要求している。この規格では、コンパイラが何をするか、何をしないかを区別しない。 この規格では、コンパイラーが行うことと、コンパイラーの生成コードが CPU に行わせることを区別していません。
このことは、2 つの疑問を生みます。どちらかが正しいのでしょうか?実際の実装はどうなっているのか?
どのように解決するのか?
を説明するよりも、むしろ
volatile
が何をするものかを説明するよりも、どのような場合に
volatile
.
-
シグナルハンドラ内の場合。に書き込むため
volatile
変数への書き込みは、標準ではシグナル ハンドラ内から実行できるほぼ唯一のことだからです。C++11 以降ではstd::atomic
を使用できますが、アトミックがロックフリーである場合のみです。 -
を扱う場合
setjmp
インテルによると . - ハードウェアを直接扱う場合で、コンパイラが読み取りまたは書き込みを最適化しないようにしたい場合。
例えば
volatile int *foo = some_memory_mapped_device;
while (*foo)
; // wait until *foo turns false
がなければ
volatile
指定がない場合、コンパイラはループを完全に最適化することができます。そのため
volatile
指定子はコンパイラに、その後の2回の読み出しが同じ値を返すと仮定してはいけないことを伝えます。
注意点として
volatile
はスレッドとは関係ないことに注意してください。上の例は、もし別のスレッドが
*foo
に書き込んでいる別のスレッドがあったとしても、acquire 操作を伴わないため、 上記の例は動作しません。
他のすべてのケースでは
volatile
の使用は、C++11 以前のコンパイラおよびコンパイラ拡張(msvc の
/volatile:ms
スイッチなど、X86/I64 でデフォルトで有効になっているもの) を扱う場合を除き、もうコード レビューをパスしないようにすべきです。
関連
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] volatileキーワードは何に役立つのでしょうか?
-
[解決済み] C++の規格では、初期化されていないboolがプログラムをクラッシュさせることは可能ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】C++コンパイルタイムエラー:数値定数の前に期待される識別子
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】Enterキーを押して続行する
-
[解決済み】なぜvolatileキーワードを使用するのですか?重複