C++ 11 std::memory_orderのすべてのレベルのメモリ バリアに相当する WinAPI、POSIX、または API-OS の他の拡張機能には、コンパイラとプロセッサ パイプラインによって操作を並べ替えるときの最適化の制限が定義されていますか?
enum memory_order {
memory_order_relaxed,
memory_order_consume,
memory_order_acquire,
memory_order_release,
memory_order_acq_rel,
memory_order_seq_cst
};
追加: WinAPI の例として、現在のMemoryBarrier()がありますが、これは に相当するだけですstd::atomic_thread_fence( std::memory_order_seq_cst );
。Windows は主に x86 システムで動作するため、プレーン ロードはセマンティクスを取得し、プレーン ストアはリリース セマンティクスを持っています: http://www.stdthread.co.uk/forum/index.php?topic=72.0
ただし、キャッシュ L3 (LLC) と x86 のパイプラインが、これらのセマンティクスに従って並べ替えの最適化をキャンセルしたとしてload()
も、コンパイラの最適化も無効にする必要があります。store()
std::memory_order_acquire/std::memory_order_release
それはWinAPIに存在します:
_ReadBarrier、_WriteBarrier、および _ReadWriteBarrierコンパイラ組み込み関数は、コンパイラの並べ替えのみを防止します。CPU が読み取り操作と書き込み操作の順序を変更しないようにするには、MemoryBarrier マクロを使用します。
GCC には、メモリ モデルを認識するアトミック操作用の組み込み関数があります。
__ATOMIC_RELAXED バリアも同期もありません。
__ATOMIC_CONSUME バリアと別のスレッドとの同期の両方に対するデータ依存性のみ。
__ATOMIC_ACQUIRE コードのホイストに対するバリアであり、別のスレッドからのリリース (またはより強力な) セマンティック ストアと同期します。
__ATOMIC_RELEASE コードのシンクに対するバリアであり、別のスレッドからの取得 (またはより強力な) セマンティック ロードと同期します。
__ATOMIC_ACQ_REL 両方向の完全バリアであり、別のスレッドで取得ロードおよび解放ストアと同期します。
__ATOMIC_SEQ_CST 両方向の完全なバリアであり、すべてのスレッドでロードの取得およびストアの解放と同期します。
また、 POSIXを使用してこのコンパイラの最適化を無効にすることはできますか?