🖥️ System

캐시 일관성 MESI/MOESI

개요

캐시 일관성(Cache Coherence)은 멀티코어/멀티프로세서 시스템에서 각 코어의 로컬 캐시에 저장된 공유 데이터의 일관성을 유지하는 메커니즘이다. 하나의 메모리 위치에 대한 여러 캐시 복사본이 존재할 때, 한 코어가 데이터를 수정하면 다른 모든 캐시의 해당 복사본이 적절하게 갱신되거나 무효화되어야 한다.

현대 멀티코어 프로세서는 각 코어가 L1/L2 캐시를 독립적으로 가지며, LLC(Last Level Cache)를 공유한다. 캐시 일관성 없이는 동일한 메모리 주소에 대한 서로 다른 값이 여러 캐시에 존재할 수 있어 프로그램의 정확성이 훼손된다. 따라서 캐시 일관성 프로토콜은 현대 컴퓨터 아키텍처의 필수적인 구성 요소이다.

핵심 개념

캐시 일관성의 필요성

멀티코어 시스템에서 각 코어는 자체 캐시를 가지며, 동일한 메모리 블록이 여러 캐시에 복사될 수 있다. 이 문제를 해결하지 않으면:

  1. 데이터 불일치: 한 코어가 수정한 데이터가 다른 코어에 즉시 반영되지 않음
  2. 순서 보장 실패: 여러 프로세서의 기입 순서가 보장되지 않음
  3. 프로그램 오류: 공유 변수에 대한 읽기/쓰기 순서가 보장되지 않아 버그 발생

캐시 일관성 요구 사항

캐시 일관성을 달성하기 위해 다음 요구 사항을 만족해야 한다:

  1. 기입 전파(Write Propagation): 한 캐시에서 수정된 데이터가 다른 모든 캐시에 전파되어야 한다
  2. 트랜잭션 직렬화(Transaction Serialization): 동일한 메모리 위치에 대한 읽기/쓰기 연산이 모든 프로세서에서 동일한 순서로 관찰되어야 한다
  3. 기입 순서 보장: 동일한 위치에 대한 기입이 어떤 순서로든 관찰되지 않아야 한다

캐시 일관성과 메모리 일관성의 차이

캐시 일관성은 같은 캐시 라인에 대한 복수 복사본이 서로 모순되지 않도록 유지하는 규칙이다. 반면 메모리 일관성(memory consistency)은 서로 다른 주소에 대한 load/store가 어떤 순서로 관찰되는지를 정의한다. MESI/MOESI는 주로 전자의 문제를 해결하며, 후자의 순서 보장은 fence, barrier, acquire/release 같은 메모리 모델 메커니즘과 함께 이해해야 한다.

즉, 모든 코어가 같은 주소 X에 대해 같은 최신 값을 보게 만드는 것이 coherence이고, X를 쓴 뒤 Y를 읽는 순서가 다른 코어에서도 같은 의미로 보장되는지를 다루는 것이 consistency이다. 실무에서는 캐시 일관성 프로토콜만으로 동기화 버그가 사라지지 않으며, store buffer와 invalidate queue 때문에 메모리 배리어가 여전히 필요하다.

False Sharing

서로 다른 변수를 접근하더라도 같은 캐시 라인에 배치되면 false sharing이 발생할 수 있다. 예를 들어 코어 A가 구조체의 필드 1을 갱신하고 코어 B가 같은 라인의 필드 2를 갱신하면, 논리적으로는 독립 데이터여도 coherence 관점에서는 동일 라인에 대한 소유권 경쟁이 일어난다.

이 경우 실제 공유 데이터 경합이 없는데도 S → M → I 전이가 반복되며 버스 트래픽과 지연 시간이 급증한다. 그래서 lock-free 큐, 카운터, 통계 구조체처럼 자주 갱신되는 데이터는 cache line padding, per-CPU 변수, NUMA-local sharding으로 분리하는 경우가 많다.

Snooping vs Directory-based

캐시 일관성 메커니즘은 크게 두 가지로 분류된다:

Snooping vs Directory

Snooping 기반

  • 모든 캐시가 버스를 모니터링하여 다른 프로세서의 접근을 감지
  • 모든 트랜잭션이 모든 프로세서에 브로드캐스트됨
  • 장점: 구현이 상대적으로 간단하고 지연 시간이 짧음
  • 단점: 버스 대역폭이 병목이 되어 확장성 제한 (보통 64개 프로세서 이하)
  • 예: Intel MESIF, AMD MOESI

Directory 기반

  • 공유 디렉토리가 각 메모리 블록의 보유자 정보를 유지
  • 프로세서가 디렉토리에 요청을 보내고, 디렉토리가 해당 프로세서에만 응답
  • 장점: 확장성이 우수함 (64개 이상의 프로세서 시스템에 적합)
  • 단점: 추가 지연 시간 (3홉 요청-전달-응답) 발생
  • 예: AMD64 칩렛 아키텍처, 대규모 SMP 시스템

디렉토리는 보통 각 캐시 라인에 대해 owner, sharer bit-vector, dirty 여부, home node 정보를 관리한다. snooping은 모든 참여자가 항상 버스를 관찰해야 하지만, directory는 해당 라인을 가진 참여자에게만 invalidate 또는 forward를 보내므로 링크 대역폭을 더 예측 가능하게 쓸 수 있다.

Write-Invalidate vs Write-Update

기입 전파 방식에 따른 분류:

특성 Write-Invalidate Write-Update
동작 기입 시 다른 모든 캐시의 복사본을 무효화 기입 시 다른 모든 캐시의 복사본을 갱신
대역폭 낮음 (무효화 메시지만 전송) 높음 (데이터를 모든 캐시에 전송)
구현 MESI, MOESI 등에서 사용 Dragon, Firefly 등에서 사용
장점 버스 트래픽 감소 읽기 지연 시간 단축
단점 재접근 시 캐시 miss 발생 기입 시 높은 대역폭 필요

비교/분석

MESI 프로토콜

MESI(Modified, Exclusive, Shared, Invalid)는 가장 널리 사용되는 캐시 일관성 프로토콜이다. 4개의 상태를 사용하여 각 캐시 블록의 상태를 관리한다.

MESI Protocol States

MESI 상태 정의

상태 의미 설명
Modified (M) 수정됨 해당 캐시에만 존재하며, 메모리와 다르게 수정됨(dirty). 다른 캐시에는 없음. 반드시 메모리에 다시 기입해야 함
Exclusive (E) 독점 해당 캐시에만 존재하며, 메모리와 동일함(clean). 쓰기 시 Modified로 전이
Shared (S) 공유 여러 캐시에 존재하며, 메모리와 동일함(clean). 읽기만 가능
Invalid (I) 무효 유효하지 않은 블록. 다시 로드해야 함

MESI 상태 전이

MESI 프로토콜의 상태 전이는 다음 두 가지 자극에 의해 이루어진다:

  1. 프로세서 요청: PrRd(읽기), PrWr(쓰기)
  2. 버스 요청: BusRd(읽기), BusRdX(쓰기/무효화), BusUpgr(업그레이드), Flush(플러시)
현재 상태 프로세서 요청 버스 요청
Invalid (I) PrRd → BusRd 발생, S 또는 E로 전이 BusRd → 무시
PrWr → BusRdX 발생, M로 전이 BusRdX/BusUpgr → 무시
Exclusive (E) PrRd → 캐시 히트, 상태 유지 BusRd → S로 전이, 데이터 전송
PrWr → 캐시 히트, M로 전이 BusRdX → I로 전이, 데이터 전송
Shared (S) PrRd → 캐시 히트, 상태 유지 BusRd → 상태 유지
PrWr → BusUpgr 발생, M로 전이 BusRdX/BusUpgr → I로 전이
Modified (M) PrRd → 캐시 히트, 상태 유지 BusRd → S로 전이, 데이터 전송
PrWr → 캐시 히트, 상태 유지 BusRdX → I로 전이, 데이터 전송

MESIF 프로토콜

Intel은 MESI에 Forward(F) 상태를 추가하여 MESIF 프로토콜을 구현했다. F 상태는 Shared 블록 중 하나에만 캐시-to-캐시 전송을 허용하여 불필요한 중복 응답을 방지한다.

MOESI 프로토콜

MOESI(Modified, Owned, Exclusive, Shared, Invalid)는 MESI에 Owned(O) 상태를 추가한 프로토콜이다. AMD에서 주로 사용하며, 캐시-to-캐시 전송을 통해 메모리 기입 없이 dirty 데이터를 공유할 수 있다.

MOESI Protocol States

MOESI 상태 정의

상태 의미 설명
Modified (M) 수정됨 해당 캐시에만 존재하며, 메모리와 다르게 수정됨(dirty). 메모리에 다시 기입해야 함
Owned (O) 소유 여러 캐시에 존재하지만, 메모리와 다르게 수정됨(dirty). 메모리 기입 책임이 있음. 다른 캐시에 데이터를 직접 전송 가능
Exclusive (E) 독점 해당 캐시에만 존재하며, 메모리와 동일함(clean). 쓰기 시 Modified로 전이
Shared (S) 공유 여러 캐시에 존재하며, 메모리와 동일하거나 Owned 상태의 캐시가 있음
Invalid (I) 무효 유효하지 않은 블록

MOESI의 Owned 상태 장점

MOESI의 핵심 특징은 Owned 상태이다:

  1. 캐시-to-캐시 전송: Modified 상태의 캐시가 다른 프로세서의 읽기 요청에 직접 데이터를 전송할 수 있음
  2. 메모리 기입 지연: 데이터가 여러 캐시에서 공유될 때 메모리 기입을 지연시킬 수 있음
  3. 대역폭 절감: 메모리 기입 없이 캐시 간 데이터 전송으로 버스 트래픽 감소

Owned 상태는 dirty 데이터의 메모리 반영 책임이 특정 캐시에 남아 있다는 점이 핵심이다. 다른 캐시는 Shared 상태로 같은 라인을 읽을 수 있지만, 최신 데이터의 기준점은 메모리가 아니라 Owned 사본이다. 그래서 snoop 응답 시 Owned 보유자가 반드시 데이터를 공급해야 stale 메모리 복사본이 사용되지 않는다.

MESI vs MOESI 비교

특성 MESI MOESI
상태 수 4 (M, E, S, I) 5 (M, O, E, S, I)
캐시-to-캐시 전송 S 상태에서 모든 캐시가 응답 가능 O 상태에서 하나의 캐시만 응답
메모리 기입 캐시-to-캐시 전송 시 메모리에도 기입 O 상태에서는 메모리 기입 지연 가능
사용처 Intel 프로세서 AMD 프로세서
장점 구현이 상대적으로 간단 대역폭 효율성 우수
단점 캐시-to-캐시 전송 시 메모리 기입 필요 구현 복잡도 증가

주요 프로세서 캐시 일관성 구현

프로세서 캐시 일관성 특징
Intel Raptor Lake MESIF F 상태로 중복 응답 방지
AMD Zen 4 MOESI O 상태로 메모리 기입 지연
Apple M3 MESI+ MESI 기반 확장
ARM Cortex-A720 MOESI ARM 아키텍처에서 MOESI 구현

동작 원리

1단계: 캐시 접근 및 일관성 검사

CPU가 메모리 주소에 접근하면:

  1. 로컬 캐시 검색: L1/L2 캐시에서 해당 주소의 블록이 있는지 확인
  2. 히트/미스 판정: 블록이 있으면 상태(MESI/MOESI)에 따라 처리
  3. 일관성 프로토콜 시작: 미스 발생 시 다른 캐시나 메모리에서 블록 로드

2단계: 기입 및 무효화

데이터를 기입할 때:

  1. S 상태에서 기입: BusUpgr 신호를 버스에 브로드캐스트하여 다른 캐시의 복사본을 무효화
  2. I 상태에서 기입: BusRdX 신호로 데이터를 로드하면서 다른 캐시의 복사본을 무효화
  3. M/E 상태에서 기입: 추가 버스 트랜잭션 없이 기입 가능

3단계: 캐시-to-캐시 전송

다른 프로세서가 데이터를 요청할 때:

  1. MESI에서: Modified 상태의 캐시가 데이터를 버스에 플러시하고 S 상태로 전이
  2. MOESI에서: Modified 상태의 캐시가 데이터를 직접 전송하고 O 상태로 전이
  3. 메모리 동기화: 필요에 따라 메모리에 기입

4단계: Store Buffer 및 Invalidate Queue

성능 최적화를 위한 메커니즘:

  • Store Buffer: 기입 지연을 줄이기 위해 기입 연산을 버퍼링
  • Invalidate Queue: 무효화 요청을 즉시 처리하지 않고 큐에 저장하여 지연 처리
  • Memory Barrier: Store Buffer와 Invalidate Queue를 강제로 플러시하여 순서 보장

5단계: Directory 기반 포워딩

directory 시스템에서는 요청 코어가 home node 또는 directory slice에 read-for-ownership 요청을 보낸다. directory는 현재 owner와 sharer 목록을 조회한 뒤, dirty owner가 있으면 forward를 보내 데이터를 직접 전달하게 하고, 공유 사본이 있으면 필요한 노드에만 invalidate를 전송한다.

이 구조는 broadcast를 줄이는 대신 directory lookup과 추가 홉이 필요하다. 칩렛 CPU, 대형 서버 소켓, mesh NoC 기반 SoC에서는 이 방식이 snooping보다 현실적이며, 최근 설계는 LLC slice와 home agent를 결합해 metadata locality를 높이는 경우가 많다.

장단점

MESI 장단점

장점 단점
메모리 대비 높은 성능 캐시-to-캐시 전송 시 메모리 기입 필요
Exclusive 상태로 불필요한 버스 트랜잭션 방지 Shared 상태에서 여러 캐시가 동시에 응답할 수 있음
Intel 프로세서에서 널리 사용 대규모 시스템에서는 버스 대역폭 병목

MOESI 장단점

장점 단점
Owned 상태로 메모리 기입 지연 가능 구현 복잡도 증가
캐시-to-캐시 전송으로 대역폭 절감 Shared 상태에서 메모리가 항상 최신 데이터가 아닐 수 있음
AMD 프로세서에서 널리 사용 처리할 상태가 추가로 필요

전체 캐시 일관성 장단점

장점 단점
멀티코어 시스템에서 데이터 일관성 보장 하드웨어 복잡도 증가
프로그램 정확성 유지 추가적인 버스 트래픽 발생
메모리 순서 보장 구현에 따라 성능 트레이드오프 존재

관련 기술

  • MESI Protocol: Illinois 대학교에서 개발된 가장 널리 사용되는 캐시 일관성 프로토콜
  • MOESI Protocol: AMD에서 사용하는 확장 프로토콜, Owned 상태 추가
  • MESIF Protocol: Intel에서 사용하는 확장 프로토콜, Forward 상태 추가
  • Directory-based Coherence: 대규모 시스템을 위한 디렉토리 기반 프로토콜
  • AMBA CHI: ARM에서 개발한 SoC용 캐시 일관성 인터페이스
  • Intel MESIF: Intel 프로세서의 캐시 일관성 구현
  • AMD MOESI: AMD 프로세서의 캐시 일관성 구현
  • 관련 문서: CPU Cache Architecture, 캐시 일관성 프로토콜, 메모리 일관성 모델, NUMA 아키텍처
  • 참고 문헌: Hennessy & Patterson, "Computer Architecture: A Quantitative Approach"; David Culler and Jaswinder Pal Singh, "Parallel Computer Architecture"; AMD64 Architecture Programmer's Manual Volume 2; Arm AMBA CHI Architecture Specification

핵심 정리

캐시 일관성은 멀티코어 시스템에서 공유 데이터의 일관성을 유지하기 위한 필수 메커니즘이다. MESI 프로토콜은 Modified, Exclusive, Shared, Invalid의 4가지 상태를 사용하여 가장 널리 사용되며, Intel 프로세서에서 주로 구현된다. MOESI 프로토콜은 MESI에 Owned 상태를 추가하여 메모리 기입을 지연시키고 캐시-to-캐시 전송을 통해 대역폭을 절감하며, AMD 프로세서에서 주로 사용된다. 두 프로토콜 모두 snooping 기반으로 구현되며, 각각 장단점이 있다. 현대 프로세서는 캐시 일관성 프로토콜을 통해 멀티코어 환경에서 데이터 일관성을 보장하고 성능을 최적화한다.