캐시 일관성 문제와 스누피·디렉토리 프로토콜

멀티프로세서 환경의 캐시 일관성 문제를 정리하고, 스누피와 디렉토리 프로토콜의 정책·구조·선택 기준을 설명한다.

2026-08-14 · 최초 발행 2025-12-28

서로 다른 캐시에 남는 같은 주소의 값

멀티프로세서 시스템에서 각 프로세서가 독립 캐시를 사용하면, 하나의 메모리 위치가 여러 캐시에 서로 다른 값으로 남을 수 있다. 한 프로세서가 데이터를 수정한 뒤 다른 프로세서가 구버전 캐시를 읽으면 프로그램 결과를 예측하기 어려워지고 데이터 무결성도 훼손된다.

캐시 일관성은 Cache Memory와 Main Memory 사이, 그리고 동일 주소를 보유한 캐시들 사이의 데이터 불일치를 다루는 문제다. 해결 방식은 공유 데이터를 캐시에서 배제하는 소프트웨어 접근부터 캐시 상태를 하드웨어가 조정하는 프로토콜까지 나뉜다.

캐시 사용 방식을 제한하는 소프트웨어 접근

모든 처리 장치가 하나의 캐시를 공유하게 하면 일관성 문제를 근본적으로 피할 수 있다. 구조가 단순하다는 장점이 있지만, 캐시 접근 경쟁이 늘어나 성능이 떨어지고 확장성도 제한된다.

공유 변수를 캐시에 저장하지 않는 방법도 있다. 컴파일러나 OS가 이를 제어하고, Non-cacheable 메모리 영역을 지정하는 방식이다. 캐시를 거치지 않아 값의 불일치는 피할 수 있지만 캐시 활용도가 낮아져 성능 저하가 따른다.

직접 접근직접 접근캐싱 금지캐싱 금지Processor 1Main MemoryProcessor 2Shared Variable

공유 버스를 감시하는 스누피 프로토콜

스누피 프로토콜에서는 모든 캐시가 공유 버스를 감시한다. 각 캐시는 주소 버스를 계속 모니터링하며 다른 캐시의 메모리 접근을 감지하고, 필요하면 자신의 캐시 상태를 자동으로 바꾼다. 일반적으로 64개 미만의 소규모 프로세서 시스템에 적용한다.

쓰기 시 복사본을 무효화하는 MESI

Write Invalidate는 Write Back 정책을 사용하며, M(Modified), E(Exclusive), S(Shared), I(Invalid)의 4개 상태를 둔다. 한 프로세서가 데이터를 쓸 때 다른 캐시의 복사본을 무효화하므로 메모리 트래픽을 줄이고 버스 대역폭을 효율적으로 사용할 수 있다.

모든 복사본에 쓰기 내용을 전달하는 방식

Write Update는 Write Through 정책과 I(Invalid), V(Valid)의 2개 플래그를 사용한다. 데이터가 쓰이면 모든 복사본을 동시에 갱신하고 즉시 메모리에 반영한다. 최신 데이터를 유지할 수 있는 대신 버스 트래픽은 증가한다.

Write Broadcast는 모든 쓰기 동작을 버스에 브로드캐스트해 각 캐시가 업데이트 정보를 받도록 한다. Write Update를 구현하는 메커니즘으로 활용된다.

"Main Memory""Processor 2 Cache""Shared Bus""Processor 1 Cache""Main Memory""Processor 2 Cache""Shared Bus""Processor 1 Cache""Write Invalidate 방식""Write Update 방식""Write X=100""Invalidate X""Mark X as Invalid""Update X=100""Write Y=200""Update Y=200""Update Y=200""Update Y=200"

대규모 시스템을 위한 디렉토리 프로토콜

디렉토리 프로토콜은 64개 이상의 대규모 프로세서 시스템에서 일관성을 유지하기 위한 방식이다. 각 캐시 블록의 공유 상태를 중앙에서 관리하고, 어떤 노드가 캐시 복사본을 보유하는지 기록한다. 불필요한 브로드캐스트를 없애 확장성이 좋지만 디렉토리를 관리하는 오버헤드가 생긴다.

모든 프로세서의 상태를 기록하는 Full Map

Full Map Directory는 모든 캐시 블록에 대해 모든 프로세서의 상태 비트를 저장한다. 프로세서가 N개이면 각 블록에는 N비트가 필요하다. 상태를 정확하게 추적할 수 있지만 메모리 오버헤드는 O(N×M)이며, N은 프로세서 수, M은 블록 수다.

공유 노드 수를 제한하는 Limited Directory

Limited Directory에서는 각 블록이 최대 K개 캐시에만 존재할 수 있다. 블록마다 필요한 크기는 K × log₂(N) 비트이며, K개를 넘으면 일부 캐시를 무효화한다. 메모리와 성능 사이의 트레이드오프를 조정하는 구조로 중간 규모 시스템에 적용한다.

연결 구조로 공유자를 추적하는 Chained Directory

Chained Directory는 연결 리스트 형태로 공유 노드를 관리한다. 디렉토리에는 체인의 시작점만 저장하고, 각 노드는 다음 노드 포인터를 가진다. 공유 수에 맞춰 동적으로 확장할 수 있어 메모리 효율은 좋지만 체인을 탐색하는 시간이 필요하다.

Chained DirectoryBlock AP0P2NULLLimited Directory (K=2)Block AP0 P2Full Map DirectoryBlock AP0:1 P1:0 P2:1 P3:0

시스템 조건에 따른 프로토콜 판단

시스템 규모가 64개 미만이면 Snoopy 프로토콜을, 64개 이상이면 디렉토리 프로토콜을 고려한다. 버스 대역폭이 제한적일 때는 Write Invalidate가 맞고, 충분한 환경에서는 Write Update를 선택할 수 있다.

공유 패턴도 기준이 된다. 읽기 위주라면 Write Invalidate가, 쓰기가 빈번하다면 Write Update가 적합하다. 메모리 예산이 제한적이면 Chained Directory나 Limited Directory를, 충분하다면 Full Map Directory를 선택한다.

캐시 라인 단위에서 발생하는 비용

False Sharing은 서로 다른 변수가 같은 캐시 라인에 놓여 불필요한 일관성 트래픽이 발생하는 현상이다. 데이터 정렬과 패딩으로 완화할 수 있다.

일관성 유지 단위는 보통 캐시 라인 크기다. 단위가 작으면 더 정밀하게 관리할 수 있지만 오버헤드가 증가한다. 반대로 단위가 크면 오버헤드는 줄어들지만 False Sharing은 늘어난다. 이 밖에도 버스 점유 시간, 상태 전이 지연, 디렉토리 접근 시간이 프로토콜 오버헤드에 포함된다.

프로세서 구현에서의 활용

Intel 프로세서는 MESI와 MESIF(Forward 상태 추가) 프로토콜을 사용한다. AMD 프로세서는 MOESI(Owned 상태 추가) 프로토콜을, IBM Power는 디렉토리 기반 프로토콜을 사용한다. ARM 멀티코어에서는 ACE(AXI Coherency Extensions) 프로토콜이 활용된다.

캐시 일관성 방식은 병렬 처리 환경의 정확성과 성능을 함께 좌우한다. 시스템 규모, 애플리케이션 특성, 하드웨어 제약을 기준으로 프로토콜과 데이터 배치를 선택해야 한다.

캐시 일관성멀티프로세서MESI디렉토리 프로토콜운영체제