現在の CPU アーキテクチャでは、主に volatile 修飾された変数の読み書き時にバリアを追加して可視性を実現しています。
invalidQueue、storeBuffer と可視性
基本的に、CPU はメモリの一貫性を実現するために mesi プロトコルを使用しています(詳細は関連コンテンツを参照してください)。mesi では、CPU の効率的な処理を実現するために、invalidQueue と storeBuffer という 2 つのデータ構造が導入されています。まず、CPU 内では、共有変数(複数の CPU、CPU0、CPU1 が共有する変数)のみが見えない問題が発生します。例えば、CPU0 と CPU1 が両方とも変数 x を高速キャッシュに保持しているとします。この時、CPU0 が x を変更し始めると、CPU0 は CPU1 に対応するキャッシュラインを無効にするよう通知します。具体的には、CPU0 は変更値を storebuffer に保存し、同時に CPU1 に通知を開始し、CPU1 は対応する無効メッセージを invalidQueue に入れ、CPU0 に処理完了を通知します。CPU0 は応答を受け取った後、変更値を storebuffer から高速キャッシュにフラッシュします。これが mesi プロトコルによる多核 CPU のキャッシュ一貫性を保証する一部です。ここで問題があることに気付くでしょう。CPU0 が変更値をメインメモリにフラッシュしていないため、CPU1 も対応する無効操作を実行していません(無効操作を実行しない場合、CPU1 は依然として高速キャッシュ内の値を取得し、無効になるまでメインメモリから対応する値を取得しません)。したがって、volatile 修飾子は、CPU0 が変更値を高速キャッシュにフラッシュする際に同時にメインメモリにフラッシュし、CPU1 が x を読み取る際には invalidQueue 内のメッセージをすべて実行して、多核 CPU 間の可視性を保証します。