*배운내용을 토대로 직접 취합하고 기술한 내용입니다.

개요

멀티스레드 환경에서 "다른 코어가 쓴 값이 보이는가?"는 명령어 재배치(Ordering)와는 별개의 문제다.

Ordering은 순서의 문제이고, Visibility는 가시성의 문제이다.

본 문서에서는 x86 CPU의 캐시 일관성 프로토콜(MESI)과 Store Buffer 동작을 정리하고,

volatile LONG + InterlockedExchange 조합에서 읽기에 Interlocked이 불필요한 이유를 실전 코드와 함께 정리한다.

<aside> 💡

관련 문서: Out-Of-Ordering & Memory Barrier

</aside>

CPU 캐시 구조

각 코어는 자체 L1/L2 캐시를 가지고 있으며, L3는 공유한다.

┌──────────┐  ┌──────────┐  ┌──────────┐
│  Core 0  │  │  Core 1  │  │  Core 2  │
│ ┌──────┐ │  │ ┌──────┐ │  │ ┌──────┐ │
│ │  L1  │ │  │ │  L1  │ │  │ │  L1  │ │
│ └──┬───┘ │  │ └──┬───┘ │  │ └──┬───┘ │
│ ┌──┴───┐ │  │ ┌──┴───┐ │  │ ┌──┴───┐ │
│ │  L2  │ │  │ │  L2  │ │  │ │  L2  │ │
│ └──┬───┘ │  │ └──┬───┘ │  │ └──┬───┘ │
└────┼─────┘  └────┼─────┘  └────┼─────┘
     └──────┬──────┴─────┬───────┘
         ┌──┴────────────┴──┐
         │    L3 (공유)      │
         └────────┬─────────┘
              ┌───┴───┐
              │  RAM  │
              └───────┘

문제는 각 코어가 같은 메모리 주소에 대해 서로 다른 캐시 복사본을 가질 수 있다는 점이다.

이를 해결하는 것이 MESI 프로토콜이다.

MESI 프로토콜 — 하드웨어 캐시 일관성

MESI는 각 캐시라인의 상태를 4가지로 관리하는 프로토콜이다.