[Computer Architecture/CacheState/MESI Protocol] 다중 코어에서의 캐시 일관성

SHark·2025년 1월 12일
0

저번 글에서는 캐시가 CPU에서 어떻게 구현이 되고 관리가 되는지 자세히(?) 알아보았습니다.
이번에는 CPU에서 사실 코어는 1개가 아니기 때문에, 여기~저기 코어에서 똑같은 캐시라인을 수정하고 읽고 합니다. (RAM은 1개) 이 말은 결국 데이터의 사본이 생긴다는 것입니다.

여러 코어에서 같은 캐시라인을 들고있는 상황

아래 표정짤을 예시로 들어봅시다. 기쁨,슬픔,짜증같은 표정을 개별적인 코어 1개로 생각하면 지금 다양한 코어에 똑같은 표정 데이터가 있게됩니다. 그러다가, 4강을 담당하는 코어에 표정사진에 변화가 생겼습니다. 일관되어야 하는 감독님의 표정이 깨지게 되었네요! 이러한 데이터는 데이터의 일관성이 깨졌다고 표현됩니다.

CPU 입장

다른 표정들이 진짜 데이터인지 4강에 올라간 표정이 진짜 데이터인지 구분을 못하게 됩니다.
정확히는, 각 코어들은 자신의 코어에 있는 데이터를 그냥 처리할 뿐이겠죠. 그렇다면, 4강 코어에서 실행될 때의 사진 데이터와 다른 표정코어에서 처리되는 사진데이터는 결과값이 달라질 겁니다.
코어에 따라서, 처리결과가 달라지네요? 사용자는 하나의 코어라고 생각할텐데.. 예. 설계결함 입니다.

즉, 데이터의 사본을 여러 코어가 갖고있고 자신의 데이터라고 착각하면서 처리한다면, 이는 설계결함입니다. 아무리 효율성을 위해서라지만, 신뢰하지 못하는 데이터를 연산하면 그건 필요없는 값이 됩니다.

따라서, cache내의 데이터는 일관될 수 있도록 방법이 마련이 되어야합니다. 그렇지 않다면 우리 소중한 CPU를 활용할 수 없게 됩니다.

캐시 일관성을 위한 정책

CPU는 내부적으로 Cache의 데이터의 일관성을 관리하기 위해서, 회사마다 조금은 다른 캐시 정책을 갖고있지만 그 중, 대표적인 MESI Protocol에 대해서 알아보겠습니다.

  • 기본적으로, 캐시 라인들을 감시하는 Bus Snooping 방식 입니다.
  • Intel에서 사용하고 있고, L3 캐시가 공유캐시(Shared Cache)라는 기준으로 설명하겠습니다.
  • ARM은 MOESI라고, Owner상태를 더 추가해서, MESI의 비효율적인 부분을 조금 더 개선한 정책을 채택했습니다. 유의해야할 점은, ARM은 애초에 L3가 각자 따로 있고, 캐시 일관성을 위한 장치가 따로 있습니다.

MESI Protocol

캐시라인은 4가지 상태를 갖게됩니다.

  • M(Modify) : 수정된 상태
  • E(Exclusive) : 유일한 상태
  • S(Shared) : 공유된 상태, 여러 코어가 함께 쓰고 있는 상태
  • I(Invalid) : 캐시 무효화.(삭제된 상태)

여기서, 캐시 라인은 오직 1개의 상태만 가질 수 있도록 정의하고 4가지의 상태 변화를 잘 지켜주면 데이터의 일관성은 깨지지 않는다는 이론입니다. 이 프로토콜은 사실 직접 RAM에서 데이터를 읽어오고, 다른 코어에서 처리되는 예시를 보면 더 이해가 잘 됩니다.

RAM에서 최초로 읽는 경우 (Exclusive)

CPU에서 A라는 데이터에 최초로 접근한다고 했을 때, Cache Miss가 쭉 나면서 RAM에서 결국 가져오게 되고, 이때의 A가 있는 캐시라인의 상태는 Exclusive상태가 됩니다.

다른 코어에서 해당 캐시 라인을 접근하는 경우 (Exclusive -> Shared)

그러다가, 스케줄링 때문에 다른 코어가 해당 일을 이어받거나, 다른 코어가 A라는 캐시라인을 같이 써야하는 상황이 온다면 L3에 먼저 접근할 것이기 때문에, L3에서 Exclusive 상태를 Shared로 바꾸어주고, 다른 코어에 모두 전파해줍니다.

Shared된 상태에서 캐시 라인을 수정하는 경우 (Shared -> Modify)

Shared된 상태에서, 한 코어에서 해당 캐시라인을 수정하는 경우 Shared상태는 Modfiy상태로 변경되고 L3까지 Modfiy상태가 됩니다. 이때, Shared->Modify가 되었기 때문에, 다른 코어에 해당 캐시라인을 무효화시키는 Invalid를 날리게 됩니다.

Modify상태에서 다른 코어가 또 접근하는 경우 (Modfiy -> Shared)

L3에서 수정된 상태라는 것은 RAM이 이미 과거의 데이터가 되었다는 이야기임. 이런 상황에서 다른 코어와 Shared가 된다면 쪼끔 불안할 수 있기 때문에 RAM에다가 Modfiy된 데이터를 쓰도록 요청해놓고, 캐시라인 상태를 Shared로 변경합니다.

이 4가지 상태변화는 중간에 다른일이 일어나지 않는 하나의 Transaction이라고 생각하면 됩니다.

I- cache 와 D-cache

글을 쓰다보니 설명을 하지 않은것이 있는데, CPU는 명령어와 데이터를 나누어서 명령어를 처리하게 됩니다. 그러다보니, cache도 자연스럽게 I - cache와 D-cache가 나누어져있고, 제가 쓴 글은 모두 Data Cache를 기준으로 작성한 것입니다. Ram에 접근한다는 것 자체가 데이터를 위한 행위이기 때문에 눈치를 채신분도 있겠지만, 정확한 설명을 위해 추가로 달아놨습니다.

그리고, CPU L1 cache총량을 할 때는 I-cache + D-cache 둘의 용량을 합한 값을 보통 표기합니다.

0개의 댓글