_ReadWriteBarrier はどのようにしてコール ツリーを上に伝播しますか?
-
23-09-2019 - |
質問
私はこの部分のテキストを見ています ドキュメンテーション Visual C++ の _ReadWriteBarrier 組み込みの場合:
Visual C ++コンパイラの過去のバージョンでは、_readWriteBarrierおよび_WriteBarrier関数はローカルでのみ施行され、コールツリーの機能には影響しませんでした。Visual C ++ 2005以降では、これらの関数はコールツリーの上に完全に強制されます。
関数内でバリアが何をするのかは理解していますが、「呼び出しツリーの上にある」ということは、関数が foo()
関数の呼び出し bar()
かどうかを知ることができます bar()
バリアが含まれているかどうか。これを可能にするために VC2005 で実際に何が変更されたのか...呼び出し規約/ABI、コンパイラーによって行われるグローバル分析、それとも何ですか?
解決
MS ドキュメントは決して優れたものではありませんが、これはその良い例です。_ReadWriteBarrier には 2 つの部分があります。
- CPUにメモリバリア(つまりmfence)を行うよう指示し、
- バリアを中心に最適化しないようにコンパイラーに指示します。
コールツリーの部分が#2を参照しているのではないかと思います。つまり:
int x = 0;
void foo()
{
x = 7;
_ReadWriteBarrier();
x = 8;
}
バリアがなければ、コンパイラによって x=7 を完全に削除できます。バリアがあると、それは残ります。さて、次のような関数はどうでしょうか。 電話 ふー?
void bar()
{
x = 3; // optimized away?
foo();
x = 4;
}
以前は x=3 が最適化されて削除されていたのではないかと思います (コンパイラにとって、それが許可されているかどうかを判断するのは難しい場合があります) が、現在は x=3 命令が正しく保持されます。
私は思う。
所属していません StackOverflow