본문 바로가기
Compiler & Computer Architecture

Memory Consistency Model

by 탁종민 2023. 10. 24.

Memory Consistency Model 의 필요성

 

아래에서 2개의 Thread로 코드들을 실행시키는 예를 보자. 

- initial

int A, flag = 0; 
- Thread 1

A = 1;
flag = 1;
- Thread 2

while (flag == 0);
print(A);

 

이때 컴파일러는 소스코드의 program order를 제대로 컴파일 되었다 해도, 오른쪽에서 A 는 0을 출력할 수도 있다. 프로세서의 OOO Execution으로 인한 메모리 access 순서가 바뀌었을 수도 있고, 아니면 하필 Thread 1 Cache에서  flag에 대한 write만 먼저 메인메모리에 먼저 반영되었을 수도 있다.

 

* 참고로 동일한 프로세서의 동일한 address에 대한 write는 그 순서가 항상 보장된다. 동일한 address에 대한 write의 순서가 바뀌면 WAW hazard이며, reordering은 WAW hazard를 허용하지 않기 때문이다.

 

위와 같이 현대와 프로세서에는 reordering같은 여러 최적화가 존재하며, 따라서 instruction의 program order 상 memory access 순서는 지켜지지 않는다고 가정해야 한다. 따라서 프로그램 코드에서의 data access 순서는 순서가 존재하지 않는 data access일 뿐이며, 이는 진정한 data access 순서를 의미하는 synchronization 과는 구분되어야 한다.

 

결론적으로 ISA( Instruction Set Architecture)는 프로그래머에게 data access 순서를 보장하는 synchronization 수단을 제공해야 한다.



Relaxed Consistency Models: The Basics and Release Consistency

프로세서 성능을 보장하면서 synchronization 을 제공하는 방법은 ordering 이다.

 

* 먼저 ordering 에 영향을 주는건 instruction reordering 과 cache coherency 임을 명심하고 이 파트를 읽어 나가자.

- read/write instruction이 reorder 되면 ordering이 지켜질 수 없다. 

- instruction reordering이 안되었다 하더라도, cache에 늦게 write한 데이터가 다른 core에게 먼저 observable 하다면 ordering이 지켜질 수 없다.

 

이제부터 operation X, Y 가 있을 때  “Y가 완료되기 전에 X가 완료됨을 보장한다" 를 X → Y 라고 표기하도록 하자.

예를들어 “write operation W가 완료되기 전에 read operation R 가 완료됨을 보장한다” 를 R → W 라고 표기한다.

 

완벽한 Sequential Consistency를 만족하려면 R → W, R → R, W → R, W → W  같은 4개의 ordering을 모두 제공해야 한다.  

 

Relaxing W → R

4개의 ordering 중  W → R 만 완화 시킨 모델을 total score ordering(TSO) 혹은  processor consistency (PC) 라고 부른다.

 

W → R 만 완화 시킨 경우, 아까전에 봤던 예제는 제대로 동작하게 된다. 

- initial

int A, flag = 0; 
- Thread 1

A = 1;
flag = 1;
- Thread 2

while (flag == 0);
print(A);

 

- Thread 1

A, flag에 대한 W → W 순서는 보장된다. 이는 instruction reordering에서도 W → W 순서를 준수하며, Cache 역시 다른 CPU Core에게 순서대로(A → flag 순서) 공유되는 것이 보장됨을 의미한다.



- Thread 2

A, flag에 대한 R → R 순서는 보장된다. 이는 instruction reordering에서도 R → R 순서를 준수하며, Cache 역시 CPU Core로 부터 순서대로(A → flag 순서) 최신화(동기화) 되는 것이 보장됨을 의미한다.



Release Consistency

R → W, R → R, W → R, W → W  4개의 ordering 모두를 완화 시킨 모델이다. acquire/release 개념을 도입해 프로그래머가 필요할 때만 ordering을 제공하고, 그 외에는 CPU가 자유롭게 실행될 수 있게 허용한다.



- acquire operation

어떤 shared variable 이 있을 때, 이 어떤 shared variable 에 대한  acquire operation을 앞으로  SA 라고 하자.

release consistency는  SA 이후의 모든 read/write operation 들이 SA 이전에 완료될 수 없게 보장한다. 

* 일반적으로 acquire operation은 load instruction의 형태이다.

- e.g) arm LDAR https://developer.arm.com/documentation/102336/0100/Load-Acquire-and-Store-Release-instructions )

 

- release operation

어떤 shared variable 이 있을 때, 이 어떤 shared variable 에 대한  release operation을 앞으로  SR 라고 하자.

release consistency는  SR 이전의 모든 read/write operation 들이 SR 이후에 완료될 수 없게 보장한다. 

* 일반적으로 release operation은 store instruction과 합쳐진 형태이다.

- e.g) arm STLR

https://developer.arm.com/documentation/102336/0100/Load-Acquire-and-Store-Release-instructions )



따라서 Release Consistency의 ordering은 다음과 같다.

- SA 이후에 발생한 모든 read/write operation 과의 ordering을 보장한다.

→ 따라서 다음을 보장한다 : SA → W, SA → R, SASA, SASR

 

- SR 이전에 발생한 모든 read/write operation 과의 ordering을 보장한다.

→ 따라서 다음을 보장한다 : R → SR, W → SR, SASR, SRSR

 

* 실제 현대 프로세서 구현에서는 shared variable을 따로 정해놓지는 않는다. 그냥 acquire/release를 적용하면 그게 shared variable 이 된다.

 

댓글