マルチスレッド コードのメモリ バリア関数とその使用時期
概要
マルチスレッド コードプログラミングでは、複数のスレッド間でデータの一貫性と一貫性を確保することが重要です。インテルは、メモリーバリアを確立し、メモリーの順序を制御するための、_mm_sfence()、_mm_lfence()、および _mm_mfence() などの組み込み関数を提供します。これらの関数をいつ使用するかを理解することは、コードを効果的かつ効率的に最適化するために不可欠です。
_mm_sfence()/NT Stores
_mm_sfence() は、通常、非テンポラル (NT) ストア。 NT ストアは弱い順序付けです。つまり、データがメモリにフラッシュされることのみが保証されますが、必ずしも特定の順序でフラッシュされるわけではありません。 NT ストアが他のスレッドからグローバルに見えるようにする必要がある場合は、NT ストアに続いて _mm_sfence() 命令を発行する必要があります。
_mm_lfence()
_mm_lfence() 命令はロード フェンスとして機能し、前のロードがリタイアする前に後続のロードが実行されるのを防ぎます。ただし、x86 CPU では、ハードウェアが明示的なバリアなしでロード順序を保証するため、通常、_mm_lfence() を使用する必要はありません。
_mm_mfence()
_mm_mfence()最も包括的なメモリバリアを構築し、逐次一貫性を確立します。これにより、後続のメモリ操作が実行される前に、以前のすべてのロードとストアがグローバルに表示されることが保証されます。 _mm_mfence() は主に、C11/C 11 std::atomic の独自の実装のローリングや永続メモリに格納されるデータの順序の制御など、特定のシナリオで役立ちます。
C 11 std:: atomic
ほとんどの場合、メモリ バリアを手動で実装する代わりに、C 11 std::atomic を使用することをお勧めします。 C 11 std::atomic は、明示的なアセンブリ コードを必要とせずにメモリの順序付けと一貫性を確保する高レベルの関数を提供します。
NT ストアとパフォーマンス
これは重要ですNT ストアは特定の使用例向けに設計されており、パフォーマンスに影響を与える可能性があることに注意してください。ストア操作は一般に、CPU にバッファされるため、目に見える実行速度には影響しません。ただし、データの一貫性と順序付けが重要な場合は、NT ストアを _mm_sfence() と組み合わせて使用して、プログラムの正しい動作を保証できます。
NT ストアとセマンティクスの取得/解放
NT ストアを使用する場合、_mm_sfence() はリリース セマンティクスを提供し、他のスレッドでの後続の操作が NT ストアの後にのみ表示されるようにします。同様に、コンシューマ スレッドが取得セマンティクス アプローチ (memory_order_acquire など) を採用している場合、_mm_sfence() は、取得されたデータがアクセスされる前に、先行するすべての NT ストアがグローバルに可視になることを保証します。
バリアとアウトオブオーダー実行
_mm_sfence()、_mm_lfence()、_mm_mfence() などのメモリ バリアは、最新の環境でのアウトオブオーダー実行に影響を与える可能性があります。 CPU。これらの CPU は、効率を高めるために命令を並行して実行しようとします。ただし、メモリバリアに遭遇した場合、CPU は後続の操作を続行する前に、前のメモリ操作がすべて完了していることを確認する必要があり、アウトオブオーダー実行によるパフォーマンスの向上が減少する可能性があります。
以上がマルチスレッド コードでメモリ バリア関数を使用する必要があるのはどのような場合ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。