Ryotta's Basic

Arch
🏗️ Arch 검증완료

메모리 일관성 모델 (Memory Consistency Model)

개요

메모리 일관성 모델(Memory Consistency Model)은 다중 프로세서/스레드 환경에서 메모리 연산의 순서와 가시성을 정의하는 규칙으로, 프로그래머와 하드웨어 간의 계약(contract) 역할을 한다. 이 모델은 한 프로세서가 수행한 메모리 쓰기가 다른 프로세서에게 어떻게, 언제 보이는지를 결정하며, 동시성 프로그래밍의 정확성에 직접적인 영향을 미친다.

메모리 일관성은 캐시 일관성(Cache Coherence)과 구별된다. 캐시 일관성은 단일 메모리 위치에 대한 여러 프로세서의 복사본이 동일하게 유지되는 것을 다루는 반면, 메모리 일관성은 여러 메모리 위치에 대한 연산 순서를 정의한다. 현대 프로세서는 성능 향상을 위해 상대적으로 약한 메모리 모델을 기본으로 채택하고 있으며, 필요 시 명시적 메모리 배리어(Memory Barrier)를 사용하여 순서를 강제한다. x86의 TSO처럼 비교적 강한 모델도 존재하지만, ARM·RISC-V·Power 계열은 더 많은 재정렬을 허용하고 소프트웨어가 동기화 지점을 명확히 표현하도록 요구한다.


핵심 개념

일관성 모델의 계층 구조

메모리 일관성 모델 계층 구조

메모리 일관성 모델은 강도(strength)에 따라 계층적으로 분류된다. 가장 강한 모델에서 가장 약한 모델로 갈수록 더 많은 순서 완화(relaxation)가 허용되며, 그에 따라 프로그래머의 책임이 증가한다.

강한 일관성 모델

Strict Consistency (엄격한 일관성)
- 가장 강한 일관성 모델
- 어떤 프로세서의 쓰기 연산이 즉시 모든 프로세서에게 보여야 함
- 실용적인 구현이 불가능하며 (즉시 정보 전송 불가), 이론적 모델로만 존재

Sequential Consistency (순서 일관성, SC)
- Lamport(1979)가 제안한 가장 널리 알려진 일관성 모델
- 모든 프로세서의 메모리 연산이 어떤 단일 순서로 실행된 것처럼 보여야 함
- 각 프로세서의 연산은 프로그램 순서(program order)를 유지해야 함
- 프로그램 순서 보장: 각 프로세서는 프로그램이 지정한 순서로 메모리 요청을 발행
- 쓰기 원자성(Write Atomicity): 메모리 요청은 단일 FIFO 큐 순서로 처리됨
- 비 결정적(non-deterministic) 결과 가능 (프로세서 간 연산 교차 순서가 실행마다 달라질 수 있음)

Causal Consistency (인과 일관성)
- 인과적으로 관련된 쓰기만 모든 프로세서에게 동일 순서로 보여야 함
- 동시 쓰기(concurrent writes)는 다른 순서로 관찰될 수 있음
- SC보다 약하지만, 인과 관계를 보장

중간 일관성 모델

Processor Consistency (프로세서 일관성, PC)
- 같은 프로세서의 쓰기는 다른 프로세서에게 동일 순서로 보여야 함
- 다른 프로세서의 쓰기는 다른 위치에 대해 일관되지 않아도 됨
- SC보다 약하지만, PRAM보다 강함

PRAM Consistency (Pipelined RAM)
- 같은 프로세서의 연산은 발행 순서대로 관찰되어야 함
- 다른 프로세서의 연산은 다른 순서로 관찰될 수 있음
- 가장 약한 일관성 모델 중 하나

약한 일관성 모델

Weak Ordering (약한 순서)
- 메모리 연산을 데이터 연산과 동기화 연산으로 구분
- 동기화 연산 사이의 데이터 연산 순서는 자유롭게 완화 가능
- 명시적 동기화(synchronization) 필요

Release Consistency (릴리스 일관성)
- 동기화 연산을 acquire(진입)와 release(이탈)로 구분
- acquire 시 로컬 메모리 연산 완료, release 시 변경사항 전파
- RCsc(SC 적용)와 RCpc(PC 적용) 두 가지 변형 존재


비교/분석

메모리 일관성 모델 비교표

메모리 일관성 모델 비교
모델 W→R W→W R→R R→W 원자성 설명
SC 유지 유지 유지 유지 유지 가장 엄격한 모델
TSO (x86) 완화 유지 유지 유지 유지 x86/x64 기본 모델
PSO (SPARC V8) 완화 완화 유지 유지 유지 SPARC V8 기본 모델
PC 완화 유지 유지 유지 완화 프로세서 일관성
약한 모델 (Alpha/RVWMO/ARM) 완화 완화 완화 완화 유지 또는 구현 의존 강한 재정렬을 허용하는 계열

프로세서별 메모리 모델

프로세서 메모리 모델 특징
x86/x64 TSO (Total Store Order) W→R 순서만 완화, 상대적으로 강한 모델
ARM (AArch32) Weakly Ordered 대부분의 순서 완화, 명시적 배리어 필요
AArch64 Weakly Ordered acquire/release 명령을 제공하지만 여전히 약한 모델
RISC-V RVWMO 기본적으로 약한 모델, 선택적 배리어
SPARC V8 TSO/PSO TSO 기본, PSO 옵션
SPARC V9 RMO (Relaxed Memory Order) 모든 순서 완화 가능
Alpha WMO (Weak Memory Order) 모든 순서 완화, 메모리 배리어 필요
PowerPC Weak Ordering SYNC/LWSYNC로 순서 강제

완화된 프로그램 순서 유형

W→R 순서 완화 (Write-to-Read)
- 쓰기 후 읽기 순서가 유지되지 않음
- TSO(x86)에서 적용
- 쓰기 지연(latency)을 숨기는 데 효과적

W→W 순서 완화 (Write-to-Write)
- 서로 다른 위치에 대한 쓰기 순서가 유지되지 않음
- PSO(SPARC)에서 적용
- 쓰기 파이프라이닝 가능

R→R 순서 완화 (Read-to-Read)
- 읽기 후 읽기 순서가 유지되지 않음
- Alpha, ARM, RISC-V에서 적용
- 읽기 명령어 재ordering 가능

R→W 순서 완화 (Read-to-Write)
- 읽기 후 쓰기 순서가 유지되지 않음
- Alpha, ARM, RISC-V에서 적용
- 가장 공격적인 완화


동작 원리

메모리 배리어 (Memory Barrier/Fence)

메모리 배리어는 프로세서에게 이전 메모리 연산이 완료될 때까지 대기하도록 지시하는 특수 명령어이다. 약한 일관성 모델에서 정확한 순서 보장을 위해 필수적이다.

주요 메모리 배리어 명령어

아키텍처 명령어 용도
x86/x64 MFENCE 전체 메모리 배리어 (모든 연산 순서 강제)
x86/x64 LFENCE 로드 배리어 (읽기 순서 강제)
x86/x64 SFENCE 스토어 배리어 (쓰기 순서 강제)
ARM DMB 데이터 메모리 배리어 (메모리 연산 순서 강제)
ARM DSB 데이터 동기화 배리어 (메모리 연산 완료 대기)
ARM ISB 명령어 동기화 배리어 (파이프라인 플러시)
RISC-V FENCE 메모리 배리어 (선택적 순서 강제)
PowerPC SYNC 전체 동기화 배리어
PowerPC LWSYNC 가벼운 동기화 배리어

배리어 사용 예시

x86 TSO에서의 배리어 사용:

; 스레드 1
MOV [data], 1      ; 쓰기
MFENCE             ; 메모리 배리어
MOV [flag], 1      ; 쓰기

; 스레드 2
MOV R1, [flag]     ; 읽기
MFENCE             ; 메모리 배리어
MOV R2, [data]     ; 읽기

ARM Weak Ordering에서의 배리어 사용:

; 스레드 1
STR R0, [data]     ; 쓰기
DMB ISH            ; 데이터 메모리 배리어
STR R1, [flag]     ; 쓰기

; 스레드 2
LDR R1, [flag]     ; 읽기
DMB ISH            ; 데이터 메모리 배리어
LDR R2, [data]     ; 읽기

쓰기 원자성 (Write Atomicity)

쓰기 원자성은 하나의 프로세서가 수행한 쓰기가 모든 다른 프로세서에게 동일한 순서로 관찰되어야 함을 보장한다.

SC에서의 쓰기 원자성:
- 모든 쓰기는 단일 FIFO 큐를 통해 처리
- 어떤 프로세서도 이전 쓰기가 완료되기 전의 값을 관찰할 수 없음

TSO에서의 쓰기 원자성:
- 자신의 쓰기는 즉시 관찰 가능
- 다른 프로세서의 쓰기는 모든 프로세서에게 동일 순서로 관찰
- Write-back 버퍼를 통해 구현

약한 모델에서의 쓰기 가시성:
- 아키텍처에 따라 다른 코어에 쓰기가 전파되는 시점이 달라질 수 있음
- 단순한 프로그램 순서만으로는 다른 코어가 같은 순서로 관찰한다고 가정할 수 없음
- 배리어, acquire/release, 원자적 연산 조합으로 필요한 관찰 순서를 만든다

저장 버퍼와 재정렬

현대 프로세서가 약한 메모리 모델을 채택하는 대표적 이유는 저장 버퍼(store buffer), 비차단 캐시, 추측 실행 때문이다. 예를 들어 x86 TSO에서는 각 코어가 자신의 저장 버퍼에 쓰기를 먼저 적재한 뒤, 나중에 캐시 계층으로 배출할 수 있다. 이 때문에 같은 코어의 이후 load가 이전 store보다 먼저 완료된 것처럼 보이는 W→R 완화가 가능하다.

ARM과 RISC-V는 이보다 더 넓은 범위의 재정렬을 허용한다. load가 서로 순서를 바꿀 수 있고, load 뒤의 store도 먼저 관찰될 수 있다. 소프트웨어는 lock, atomic, fence를 통해 "이 지점 이전의 갱신이 먼저 보여야 한다"는 의도를 명시해야 하며, 운영체제 커널과 런타임은 이런 제약 위에서 동기화 원시를 구현한다.

동기화 메커니즘

동기화는 약한 일관성 모델에서 정확한 순서를 보장하는 핵심 메커니즘이다.

Acquire-Release 동기화:
- Acquire: critical section 진입 시 사용, 이후 메모리 연산이 이전 연산보다 앞서지 않도록 보장
- Release: critical section 이탈 시 사용, 이전 메모리 연산이 이후 연산보다 뒤에 오도록 보장

Lock/Unlock 동기화:
- Lock 획득 시 acquire semantic 적용
- Lock 해제 시 release semantic 적용
- spinlock, mutex 등 다양한 구현

Seqlock (Sequential Lock):
- 읽기 전용 데이터에 최적화
- 쓰기 시 version counter 증가
- 읽기 시 version 변경 여부 확인


장단점

강한 일관성 모델 (SC)

장점:
- 프로그래밍 용이성: 명시적 동기화 불필요
- 직관적인 동작: 프로그램 순서대로 메모리 연산이 보임
- 디버깅 용이성: 재현 가능한 동작

단점:
- 성능 오버헤드: 모든 메모리 연산 순서 강제
- 하드웨어 구현 복잡성: 전체 캐시 코히런시 필수
- 확장성 한계: 다중 프로세서에서 병목 발생

약한 일관성 모델 (WMO)

장점:
- 성능 향상: 메모리 연산 재ordering으로 병렬성 극대화
- 하드웨어 효율성: 캐시 코히런시 비용 감소
- 확장성: 대규모 시스템에서 효과적

단점:
- 프로그래밍 복잡성: 명시적 메모리 배리어 필요
- 디버깅 어려움: 비 결정적 동작으로 인한 재현 문제
- 버그 잠재력: 순서 오류로 인한 레이스 컨디션

TSO (x86)

장점:
- 상대적으로 강한 보장: W→R 순서만 완화
- 프로그래밍 용이성: 약한 모델 중 가장 직관적
- 기존 코드 호환성: SC 코드가 대부분 정상 동작

단점:
- 성능 제한: 모든 프로세서가 동일한 제약을 받음
- 최적화 한계: W→W, R→R 재ordering 불가


관련 기술

캐시 일관성 프로토콜

  • MESI, MOESI, MESIF 프로토콜
  • 디렉터리 기반 일관성
  • 버스 스누핑 메커니즘

동시성 프로그래밍

  • 뮤텍스(Mutex), 세마포어(Semaphore)
  • C/C++11 메모리 모델과 std::atomic
  • Java Memory Model(JMM)
  • 퍼포먼스 카운터(Performance Counter)
  • 하드웨어 모니터링 도구 (PEBS, LBR)

관련 표준 및 사양

  • ARM Architecture Reference Manual
  • Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 3A, Ch. 10
  • Intel 64 and IA-32 Architectures Software Developer's Manual
  • The RISC-V Instruction Set Manual, Volume I: Unprivileged ISA, RVWMO Chapter
  • RISC-V Privileged Architecture Specification
  • SPARC V8/V9 Architecture Manual

참고 문헌

  • Leslie Lamport, "How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Programs" (1979)
  • Sewell et al., "x86-TSO: A Rigorous and Usable Programmer's Model for x86 Multiprocessors" (CACM, 2010)
  • Sarita V. Adve, Kourosh Gharachorloo, "Shared Memory Consistency Models: A Tutorial" (IEEE Computer, 1996)

핵심 정리

  1. 메모리 일관성 모델은 다중 프로세서 환경에서 메모리 연산의 순서와 가시성을 정의하는 하드웨어-소프트웨어 계약이다.

  2. Sequential Consistency (SC)는 가장 강한 실용적 모델로, 모든 프로세서가 동일한 연산 순서를 관찰해야 하지만 성능 오버헤드가 크다.

  3. 현대 프로세서는 상대적으로 약한 메모리 모델을 기본으로 채택하여 성능을 향상시키며, x86은 TSO, ARM은 weakly ordered 모델, RISC-V는 RVWMO를 사용한다.

  4. 메모리 배리어(Memory Barrier)는 약한 일관성 모델에서 정확한 순서를 보장하기 위한 필수 도구로, 각 아키텍처마다 고유한 명령어를 제공한다.

  5. 프로그래머의 이해가 필수적이며, 올바른 동기화 없이는 레이스 컨디션과 비 결정적 동작이 발생할 수 있다.