컴퓨터구조

캐시 일관성(cache coherence)과 프로토콜

fish9903 2023. 2. 7. 11:15

캐시 메모리는 프로세서가 data를 얻기 위해 메인 메모리를 참조하지 않도록 할 수 있어, 속도 향상에 많은 도움을 준다.

하지만 캐시 메모리를 사용하면 같은 data가 여러 곳의 메모리에 존재하는 경우가 생기는데, 이 여러 곳에 존재하는 data들이 같은 값 또는 유효한 값을 가지도록 하는 것이 중요하다. 이것을 캐시 일관성(cache coherence) 문제라고 한다.

 

coherence와 consistency

coherence는 한 location에 있는 data를 읽어올 때, 이 data가 유효 또는 가장 최신인 data임을 보장하는 의미이고, 

consistency는 여러 location에 존재하는 data들을 가져오거나 실행할 때, 정해진 순서로 가져오거나 실행되는 것을 보장하는 의미이다.

 

쓰기 정책(Wirte Policy)

프로세서가 한 개인 싱글프로세서 환경에선 캐시가 여러개 존재할 때(여러 level) 한 캐시에 일어난 변경을 다른 계층의 메모리로 바로 전달할 것인지 미룰지 정하면 된다.

변경점을 바로 다른 계층의 메모리로 전달하여 일관성 문제를 해결하는 방법을 write through,

변경점을 바로 다른 계층의 메모리로 전달하는 것이 아닌, 변경이 일어난 캐시에만 저장해두고 이후 변경이 일어난 line이 캐시에서 evicted(방출)될 때 메인 메모리에 반영하는 방법을 write back이라고 한다.

 

하지만 프로세서가 여러개인 멀티프로세서 환경에선 각 프로세서마다 전용 캐시가 존재하고, 여러 프로세서가 공유하는 캐시도 존재하는 등, 좀 더 복잡한 구조를 가지므로 캐시 일관성 문제는 더 복잡해진다.

 

multicore와 multiprocessor

multicore는 하나의 CPU에 core라고하는 독립적인 실행 유닛이 두 개 이상 존재하는 구조

multiprocessor는 두 개 이상의 CPU가 존재하는 구조. 하나의 메모리를 공유하는 SMP(Symmetric MultiProcessor)구조를 가짐

multicore는 single program을 빠르게 동작시킬 수 있고, multiprocessor는 프로그램을 parallel하게 실행하는데 적합하다.

 

멀티프로세서 캐시 일관성(Multicore Cache Coherence)

같은 메인 메모리를 여러 프로세서가 공유하는 SMP환경을 가정하자

SMP

각 프로세서에는 한 개 이상의 캐시가 존재하고, 각 프로세서와 메인 메모리는 bus로 연결되어 있다.

이때 메인 메모리와 Processor1에 X라는 변수에 100이 저장되어 있다고 가정하자. 

이 상태에서 Processor2가 같은 X라는 변수를 읽고, 값을 200으로 바꾸었다면 어떻게 될까?

메인 메모리와 Processor1에 저장되어 있는 X값과 Processor2에 저장되어 있는 X값이 달라지게 되는데 어느 X값이 가장 유효한 값인지 알 수 없다.  따라서 어느 위치에 있는 값이 유효한 값인지 알 수 있도록 할 필요가 있는데, 이것이 캐시 일관성 문제이다.

 

일관성을 유지하기 위해 하드웨어적 방법, 소프트웨어적 방법이 존재한다. 소프트웨어적 방법으론 컴파일러가 이를 관리하는 방법 등이 있고, 하드웨어적 방법으로는 캐시 프로세서나 캐시가 값이 변경됨을 알리는(broadcast)하는 방법, 디렉토리(directory)를 만들어 관리하는 방법 등이 있다. 여기서는 broadcast하는 방법을 보자

 

Bus Snooping(Bus-Based Protocols)

"snoop"은 관찰한다(monitor)는 뜻으로, 각 프로세서 또는 캐시가 bus를 snoop하는 방법으로 캐시 일관성 문제를 해결할 수 있다.

각 프로세서 또는 캐시는 bus를 snoop하고 있다가, 캐시에 저장되어 있는 data에 대한 동작(read/write request)을 감지하면 이와 관련된 data에 동작을 수행한다. 한 캐시에 있는 data에 변경(write)이 일어났을 때, 이 캐시에서 bus로 변경이 일어났다는 신호를 보낸다. 이 신호를 받은 다른 캐시들은 그 data를 처리하는데 즉시 값을 동일하게 변경(update)하는 방법과 해당 data를 유효하지 않게(invalidate)하게 만드는 방법이 있다.

 

즉시 값을 동일하게 update하는 방법은 해당 data가 자주 변경되지 않는 경우 효율적이고 완벽한 coherence를 이루었다고 할 수 있지만, 한 data에 변경(write)이 있을 때마다 bus에 신호와 변경된 data를 주어야 하기 떄문에 bus에 많은 부담이 된다. 이 방법은 write through policy라고 할 수 있고 동일하게 bus가 bottleneck이 될 가능성이 크다.

 

다른 방법인 단지 해당 data를 invalidate한 상태로 바꾸는 방법은 모든 메모리가 일관성을 유지하지는 않지만, 한 data에 변경(write)이 있을 때 한번만 신호를 보내 다른 캐시에 존재하는 해당 data를 invalidate하게 만들면 되기 때문에 bus에 부담이 적다. 변경된 값을 바로 다른 메모리에 반영하지 않는다는 점에서 write back policy라고 볼 수 있다.

 

MSI Protocol

Bus snooping 방법 중 Invalidate protocol에서 기본이 되는 MSI protocol을 보자

MSI protocol

MSI protocol에는 다음 세 가지 상태가 존재한다.

1. M = Modified

해당 캐시 line의 data는 이 캐시에서만 변경이 이루어진 상태(가장 최근에 변경이 일어난 곳)

메인 메모리와 값 다름(dirty)

 

2. S = Shared

해당 캐시 line의 data는 다른 위치의 캐시에도 같은 값으로 존재하는 상태

메인 메모리와 값 동일(clean)

 

3. I = Invalidate

해당 캐시 line의 data는 유효하지 않은 상태

 

프로세서 안에 있는 캐시는 다른 bus를 snoop하고 있으므로 두 가지 action을 탐지할 수 있다.

1. Local Processor Action

캐시가 속해 있는 프로세서에서 read, write 동작이 일어나는 경우

캐시의 변경이 발생하면 발생 했다고 bus를 통해 broadcast한다.

 

초기 캐시의 모든 line은 I상태로 초기화된다. 

 

I 상태에서 local processor가 read 동작

--> read miss가 발생하고 메인 메모리에서 data를 읽어 캐시에 저장한다. 다른 캐시가 해당 data에 대해 M 상태인 line을 가진 경우, M 상태인 캐시에서 data를 읽어온다. (M 상태인 캐시는 S 로 변경됨)

(line의 상태: I --> S)

 

I 상태에서 local processor가 write 동작

--> write miss가 발생하고 메인 메모리에서 data를 읽어오고 그 값을 변경한다. 값이 변경되었으므로 다른 캐시에 해당 data가 존재하면 invalidate하라는 신호를 bus로 전달

(line의 상태: I --> M)

 

S 상태에서 local processor가 write 동작

--> write hit이 발생하고 캐시의 값을 변경한다. 값이 변경되었으므로 다른 캐시에 해당 data가 존재하면 invalidate하라는 신호를 bus로 전달

(line의 상태: S-->M)

 

2. Bus Action(Other Process Action)

Bus에서 신호가 들어오는 경우

Bus에서 신호가 들어오는 경우는 다른 프로세서에서 캐시에 대한 동작이 일어났다는 뜻

Bus를 snoop하다가 신호를 받으면 이에 따라 해당 캐시 line의 상태를 update한다.

 

S 상태에서 bus action으로 write가 들어온 경우

--> Bus action으로 write가 들어온 경우는 다른 프로세서에서 해당 data가 있는 캐시 line을 write한다는 뜻이고, 더이상 이 캐시의 해당 line은 유효하지 않으므로 상태를 I로 변경한다.

(line의 상태: S --> I)

 

M 상태에서 bus action으로 write가 들어온 경우

--> Bus action으로 write가 들어온 경우는 다른 프로세서에서 해당 data가 있는 캐시 line을 write한다는 뜻이고, 더이상 이 캐시의 해당 line은 유효하지 않으므로 상태를 I로 변경한다.

(line의 상태: M --> I)

 

M 상태에서 bus action으로 read가 들어온 경우

--> Bus action으로 read가 들어온 경우는 다른 프로세서에서 해당 data가 있는 캐시 line을 read한다는 뜻이고, 더이상 이 캐시의 해당 line은 이 캐시가 독점하지 않게 되므로 상태를 S로 변경한다. 이 경우는 가장 최신 data가 M상태였던 이 캐시에 존재하므로 M상태인 캐시의 해당 line의 data를 메인 메모리에 전달하여 메인 메모리를 업데이트 한다. 그리고 가지고 있던 data를 read하려는 캐시로 전달한다.

(line의 상태: M --> S)

 

다음은 MSI protocol의 예시이다.

 

MESI Protocol

MSI protocol은 bus-based protocol 중 기본이 되는 protocol이지만 단점이 존재한다.

오직 한개의 캐시가 특정 data를 가지고 있을 때도 그 캐시는 S 상태가 된다는 것이다. 이게 문제가 되는 이유는 이 S 상태에서 값을 바꾸면(write) 무조건 invalidate 신호를 bus를 통해 broadcast해야 하기 때문이다. 다른 캐시에는 이 data가 없는데 invalidate 신호를 bus로 전달하면 이는 bus 낭비다. 따라서 오직 이 data는 이 캐시에만 존재한다는 Exclusive상태를 추가하여 이를 해결한 protocol이 MESI protocol이다.

 

MESI

E = Exclusive

오직 이 캐시에 존재하는 data를 의미한다.

메인 메모리와 값 같음(clean)

 

Local Processor Action

I가 read action에서 갈 수 있는 상태가 2가지다. 만약 읽어오려는 data가 다른 캐시에 존재한다면 S로 바뀌고, 다른 캐시에도 없다면 직접 메인 메모리에서 읽어와 E로 바뀐다. E상태 또한 local processor에서 write 동작이 발생하면 M상태로 변경하고 다른 캐시의 해당 data를 invalidate한다. 이때는 다른 캐시에 해당 data가 없으므로 bus에 신호를 주지 않는다.

 

특징으로는 E에서 M상태로 변할때 bus에 아무런 신호를 주지 않고도 조용하게(sliently) 바뀐다는 점이 있다.

 

Bus Action

E상태도 다른 상태와 마찬가지로 다른 프로세서에서 write동작이 발생했다는 신호를 받으면 I상태로 변하고, read동작이 발생했다는 신호를 받으면 S상태로 변한다.

 

다음은 MESI protocol의 예시이다.

이러한 MESI protocol은 Intel의 x86 architecture에서 사용된다.

 

MOESI Protocol

MESI protocol에도 비효율적인 부분이 존재한다. M에서 S상태로 바뀔때 꼭 메인 메모리에 data를 저장해야 하는가에 대한 문제이다. MSI와 MESI protocol에선 메인 메모리가 clean한 data를 가지고 있고, 이를 다른 캐시에 전달하는 역할을 한다. MOESI protocol은 Owned 상태를 추가하여, 이 상태에 있는 data를 가진 캐시가 메인 메모리의 역할을 하게 수정한 것이다. 메인 메모리에 접근하는 것보다 캐시끼리 data를 교환하는 것이 더 빠르기 때문에 더 빠르게 동작한다.

MOESI

O = Owned

 

Owned 상태는 해당 data에 대한 책임이 있는 상태라고 할 수 있다. 해당 data가 가장 마지막으로 변경된 캐시의 line에 상태가 owned으로 되며, 다른 캐시에서 해당 data의 clean상태를 요구할 경우 메인 메모리가 아닌 owned 상태의 line을 가진 캐시가 이를 제공한다.

Line의 상태가 M인 data를 가진 캐시가 다른 캐시로 부터 이 data의 read 요구를 받을 경우, M에서 O로 상태가 변한다.

 

이후 owned 상태의 line이 캐시에서 evicted될 경우, 이 data가 메인 메모리에 반영된다.

 

다음은 MOESI Protocol의 예시이다.

 

이러한 MOESI Protocol은 ARM에서 사용된다.