2

Visual C++ の _ReadWriteBarrier 組み込みのドキュメントで、次のテキストを見ています。

以前のバージョンの Visual C++ コンパイラでは、_ReadWriteBarrier および _WriteBarrier 関数はローカルでのみ適用され、呼び出しツリーの上位の関数には影響しませんでした。Visual C++ 2005 以降では、これらの関数は呼び出しツリー全体に適用されます。

関数内でバリアが何をするかは理解していますが、「呼び出しツリーの上」は、関数foo()を呼び出す関数がバリアを含むbar()かどうかを知ることができることを意味しているようです。bar()これを可能にするために VC2005 で実際に変更されたものは何ですか... 呼び出し規約/ABI、コンパイラによって行われるいくつかのグローバル分析、または何ですか?

4

1 に答える 1

1

MS ドキュメントは決して素晴らしいものではなく、これはその良い例です。_ReadWriteBarrier には 2 つの部分があります。

  1. CPU にメモリ バリア (つまり mfence) を実行するように指示します。
  2. バリアを回避して最適化しないようにコンパイラーに指示します。

コール ツリーの部分が #2 を参照していると思われます。すなわち:

int x = 0;

void foo()
{
   x = 7;
   _ReadWriteBarrier();
   x = 8;
}

バリアがなければ、コンパイラは x=7 を完全に削除できます。障壁があれば、それはとどまります。では、 fooを呼び出す関数はどうでしょうか。

void bar()
{
   x = 3;  // optimized away?
   foo();
   x = 4;
}

過去に x=3 が最適化されていた可能性があると思います (これは、コンパイラが許可されているかどうかを判断するのが難しい場合があります) が、現在は x=3 命令を正しく保持します。

おもう。

于 2010-01-29T05:00:14.927 に答える