멀티코어 CPU 구조를 공부하다 보면 어느 순간부터는 “코어가 많아지면 그냥 무조건 빨라지는 건 아닌가?”라는 의문이 들기 시작한다. 나도 예전에는 CPU 코어 수가 늘어나면 성능도 거의 비례해서 올라갈 거라고 생각했었다. 실제로 광고에서도 8코어, 16코어, 32코어 같은 숫자를 강조하니까 당연히 코어가 많을수록 무조건 좋은 줄 알았다. 그런데 NUMA 구조와 메모리 locality 같은 개념들을 보다 보니까 현대 CPU는 단순히 코어를 많이 넣는 것보다 “코어끼리 데이터를 어떻게 공유하고 동기화하느냐”가 훨씬 더 어려운 문제라는 걸 느끼게 됐다. 그리고 그 중심에 등장하는 핵심 개념 중 하나가 바로 Cache Coherency다. 처음 이름만 들었을 때는 그냥 CPU 캐시(Cache) 동기화 정도로 생각했는데, 구조를 이해하고 나니까 왜 멀티코어 CPU 설계가 점점 어려워지고 있는지 조금 감이 오기 시작했다. 특히 인상 깊었던 건 현대 CPU는 계산 자체보다 “각 코어가 같은 데이터를 어떻게 일관되게 바라보게 만들 것인가” 때문에 엄청난 복잡성이 생긴다는 점이었다. 나도 처음에는 메모리는 그냥 RAM 하나 공유하면 끝인 줄 알았는데, 실제로는 각 코어마다 따로 존재하는 캐시 때문에 예상보다 훨씬 복잡한 문제가 발생하고 있었던 것이다.

멀티코어 CPU는 각 코어마다 자기만의 캐시를 사용한다
현대 CPU는 메모리 속도가 CPU 계산 속도를 따라오지 못하기 때문에 캐시(Cache)를 굉장히 중요하게 사용한다. 쉽게 말하면 CPU가 자주 사용하는 데이터를 RAM까지 가지 않고 더 가까운 작은 메모리에 저장해두는 구조다. 문제는 멀티코어 CPU 환경에서는 각 코어마다 자기만의 L1/L2 캐시를 가지고 있다는 점이었다. 처음에는 나도 “그냥 캐시 여러 개 쓰면 더 빠른 거 아닌가?”라고 생각했는데, 실제로는 여기서 엄청 복잡한 문제가 생기기 시작한다고 한다. 예를 들어 CPU Core A와 Core B가 같은 변수 데이터를 동시에 사용한다고 가정해보자. Core A는 자기 캐시에 있는 데이터를 수정했고, Core B는 여전히 예전 데이터를 자기 캐시에 가지고 있을 수도 있다. 즉 같은 메모리 데이터를 코어마다 서로 다르게 보고 있는 상황이 발생할 수 있는 것이다. 나도 처음에는 “그럼 그냥 RAM 다시 읽으면 되지 않나?” 싶었는데, 현대 CPU는 성능 때문에 캐시를 적극적으로 사용하다 보니까 이런 데이터 불일치 문제가 굉장히 중요해진다고 한다. 특히 멀티스레드 서버나 병렬 연산 환경에서는 여러 코어가 같은 데이터를 동시에 접근하는 일이 매우 많기 때문에, 캐시 일관성(Cache Coherency)을 유지하는 작업 자체가 엄청난 비용이 될 수 있다고 한다. 결국 멀티코어 CPU는 단순히 계산 코어를 많이 넣는 게 아니라, “모든 코어가 같은 데이터를 일관되게 보게 만드는 문제”까지 해결해야 하는 굉장히 복잡한 구조였던 것이다.
Cache Coherency는 코어끼리 캐시 상태를 계속 동기화해야 한다
Cache Coherency의 핵심은 굉장히 단순하다. 바로 여러 CPU 코어가 같은 메모리 데이터를 항상 일관되게 바라보게 만드는 것이다. 문제는 이를 위해 코어끼리 엄청난 동기화 작업이 필요하다는 점이었다. 예를 들어 Core A가 어떤 데이터를 수정하면 다른 코어들의 캐시 안에 있는 이전 데이터는 무효화(Invalidate)하거나 최신 상태로 갱신해야 한다. 그렇지 않으면 각 코어가 서로 다른 데이터를 기반으로 계산하게 될 수도 있기 때문이다. 현대 CPU는 이를 위해 MESI Protocol 같은 캐시 일관성 프로토콜을 사용한다고 한다. 처음에는 나도 이름만 보고 엄청 어려운 알고리즘인 줄 알았는데, 기본 개념은 “이 데이터가 누구 캐시에 있고, 수정 가능한 상태인지”를 계속 관리하는 방식에 가까웠다. 문제는 코어 수가 많아질수록 이런 동기화 비용도 폭발적으로 증가할 수 있다는 점이었다. 예를 들어 수십 개 코어가 같은 데이터를 계속 수정하려고 하면 캐시 invalidation 메시지와 coherence traffic이 엄청나게 발생할 수 있다고 한다. 결국 CPU는 실제 계산보다 캐시 상태 맞추는 데 더 많은 시간을 쓰게 되는 상황도 생길 수 있는 것이다. 나도 처음에는 멀티코어 CPU가 단순히 계산기 여러 개 붙여놓은 느낌인 줄 알았는데, 실제로는 각 코어가 서로 “내 데이터 최신 상태 맞아?”를 계속 확인하는 엄청 복잡한 협업 구조라는 게 꽤 인상 깊었다. 특히 False Sharing 같은 문제도 결국 이런 Cache Coherency 비용 때문에 발생한다는 걸 알고 나니까 왜 멀티스레드 최적화가 어려운지도 조금 이해가 되기 시작했다.
그래서 현대 CPU는 계산보다 데이터 공유 비용이 더 큰 문제가 되기도 한다
지금까지 공부했던 NUMA, Huge Page, RDMA 같은 기술들을 보면 공통된 흐름이 하나씩 있었다. 바로 CPU가 데이터를 기다리거나 불필요하게 이동하지 않게 만드는 방향이라는 점이다. Cache Coherency 역시 완전히 같은 흐름 위에 있다. 다만 이번에는 메모리 접근 자체가 아니라 “CPU 코어끼리 데이터를 어떻게 효율적으로 공유할 것인가”가 핵심 문제인 것이다. 특히 최신 서버 CPU는 코어 수가 계속 증가하고 있기 때문에 캐시 일관성 유지 비용도 훨씬 더 중요해지고 있다고 한다. 예를 들어 AI 서버나 데이터베이스 서버처럼 멀티스레드 작업이 엄청 많은 환경에서는 캐시 동기화 자체가 주요 병목으로 등장할 수도 있다고 한다. 나도 처음에는 CPU 성능이라는 게 단순 계산 속도 문제인 줄 알았는데, 실제로는 데이터 공유와 캐시 동기화가 훨씬 더 어려운 문제라는 게 꽤 흥미로웠다. 특히 현대 CPU 설계는 단순히 코어를 많이 넣는 경쟁이 아니라, 코어끼리 데이터를 얼마나 효율적으로 공유하고 coherence traffic을 줄일 수 있는가의 경쟁으로까지 발전하고 있다는 느낌이 강했다. 결국 현대 멀티코어 CPU는 단순 계산기 집합이 아니라, 엄청난 양의 캐시 동기화와 데이터 일관성을 유지하는 거대한 협업 시스템에 가까웠던 것이다. 이걸 공부하면서 가장 인상 깊었던 건 현대 컴퓨터 성능은 단순 계산 속도가 아니라, 데이터를 얼마나 효율적으로 공유하고 동기화할 수 있는가의 경쟁으로 계속 바뀌고 있다는 점이었다.
한 줄로 정리하면 Cache Coherency는 여러 CPU 코어가 같은 메모리 데이터를 항상 일관되게 바라보도록 캐시 상태를 동기화하는 구조이며, 멀티코어 환경에서 coherence traffic과 캐시 invalidation 비용 때문에 CPU 설계를 매우 어렵게 만드는 핵심 문제다.