_WriteBarrier
Microsoft 固有の仕様 →
呼び出しの時点で終了するメモリへの強制変換の書き込み。
注意 |
---|
_ReadBarrier、 _WriteBarrierと _ReadWriteBarrier コンパイラ組み込みはコンパイラの並べ替えだけなります。読み取り順序と書き込み操作で CPU を回避するには、 MemoryBarrier のマクロを使用します。 |
void _WriteBarrier(void);
必要条件
組み込み |
アーキテクチャ |
---|---|
_WriteBarrier |
x86、 IPF、 x64 |
ヘッダー ファイル <intrin.h>
解説
_ReadBarrier、 _WriteBarrierと _ReadWriteBarrier の関数は Visual C++ コンパイラによって最適化されたマルチスレッド プログラムの適切な操作を確認できます。適切に最適化されたプログラムは、シングル スレッドで実行時に複数のスレッドでように実装する方法と同じ結果になります。
最適化されたプログラムが正しく動作することを確認するには、 _WriteBarrier 関数がメモリに呼び出しの時点で終了するように書き込みが強制されます。呼び出しの後に、別のスレッドの呼び出しを行ったスレッドがメモリに保留中の書き込みがあります。という恐れせずにメモリにアクセスできます。詳細については、_ReadWriteBarrier の解説を参照してください。
[!メモ]
Visual C++ コンパイラの旧バージョンでは、 _WriteBarrier の _ReadWriteBarrier と関数は、ローカルにのみ適用され、コール ツリーの最上位の関数には影響を与えませんいません。これらの関数は、コール ツリーの最上位に表示して実装されます。
使用例
次の例は _ReadWriteBarrierに示すように似ています。関数 f は、ローカル変数 xに 2 個のを代入します。_WriteBarrier なしで最初の代入は無意味な代入として最適化されます。_WriteBarrier によって代入は、どちらも保持され、最初の代入が null ポインターを逆参照しようとするとアクセス違反が発生します。
// intrinsics_writebarrier.c
// compile with: /O2 -DNO_BARRIER
// This code contains an error--dereferencing a null pointer--
// which will be optimized away as a useless assignment.
// Omit the NO_BARRIER command line to activate the Write Barrier.
// With the barrier activated, the assignment is not optimized away
// and causes an access violation.
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
#include <stdio.h>
#include <intrin.h>
#pragma intrinsic(_WriteBarrier)
int x = 0;
__declspec(noinline) int f(int* p)
{
x = *p;
#ifndef NO_BARRIER
_WriteBarrier();
#endif
x = 7;
return x;
}
// If code is EXCEPTION_ACCESS_VIOLATION it should be the
// attempt to read from the NULL pointer we passed in, so
// we handle the exception.
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
if (code == EXCEPTION_ACCESS_VIOLATION)
{
printf_s("AV\n");
return EXCEPTION_EXECUTE_HANDLER;
}
// If not what we were looking for, we don't want to handle it.
return EXCEPTION_CONTINUE_SEARCH;
}
int main()
{
__try
{
// Should return only if the first assignment is
// optimized away.
f(NULL);
printf_s("Assignment was optimized away!\n");
}
__except(filter(GetExceptionCode(), GetExceptionInformation()))
{
// We get here if an Access violation occurred.
printf_s("Access Violation: assignment was not optimized away.\n");
}
}
出力例
/DNO_BARRIER:なし
AV
Access Violation: assignment was not optimized away.
/DNO_BARRIER の場合:
Assignment was optimized away!