Understanding CPU Caching and Performance 01/04

By | 2006/03/30

Understanding CPU Caching and Performance

by Jon “Hannibal” Stokes

처음, 본 사이트를 시작했을 때, 인텔은 첫 번째 셀러론 프로세서를 로우엔드 시장을 겨냥해서 출하했었다. 당시, 펜티엄 II가 갖고 있던 백사이드 캐시를 셀러론은 갖고 있지 않았기 때문에, 반대로 극도의 오버클럭킹도 셀러론에서는 가능하였다. 실제로 오버클럭킹을 주류로 옮긴 주역이 바로 셀러론이라 할만 하며, 본 사이트는 오버클럭킹 가이드를 어떻게, 왜 하는 지에 대한 상세한 기사를 올린 적이 있다. 프랑크 먼로(Frank Monroe)의 셀러론 오버클럭킹 FAQ[http://arstechnica.com/paedia/celeron_oc_faq.html] 는 당시 제일 유명한 기사였으며, “셀러론”과 “오버클럭킹”을 야후에서 검색한 이들은 바로 먼로의 FAQ 페이지로 오곤 했다. (심지어는 필자의 여자친구가 말하기를, 필자와 만나기 전에 야후를 통해 본 사이트의 FAQ를 읽은 적이 있었다는 것이다.)

오 버클럭킹과 더불어, 셀러론에는 “캐시 없음”의 기능이 특히 주목받았다. 셀러론에서의 퀘이크 벤치마킹은 캐시가 있는 펜티엄 II와 거의 비슷했기 때문에 더더욱 그러했다. 당시 뉴스그룹과 각종 BBS는 이 현상에 대해 논의하였지만 실제로 캐시가 어떤 방식으로 퍼포먼스를 늘리는 데에 대해서 올바르게 이해하는 이들은 거의 없었다. 개인적으로 지금도 마찬가지리라 생각한다. 하지만 현재의 시스템 디자인에서는 캐시가 다시금 중요해졌다. RAMBUS와 DDR, 그 외 차세대 메모리 기술[http://arstechnica.com/paedia/r/ram_guide/ram_guide.part1-1.html] 이 나왔음에도 불구하고, CPU 클럭 속도와 퍼포먼스는 메인 메모리 퍼포먼스보다 더더욱 빠르게 증대하였다. 결과적으로 L1과 L2, L3 캐시는 상대적으로 느린 RAM이 전체 시스템 퍼포먼스를 떨어뜨리지 않도록 막는 역할을 맡았다.

본 기사는 CPU 캐시와 퍼포먼스에 대한 일반적인 소개를 내용으로 하며, spatial과 temporal locality와 set associativity와 같은 근본적인 캐시의 개념과, 애플리케이션이 각기 캐시를 이용하는 방법, 메모리 위계 등을 기술한다. 이와 같은 내용에 더불어, 다음 기사에는 인텔 P4와 모토로라 G4e 기반의 시스템에서 실제로 캐시와 메모리 서브시스템이 어떻게 돌아가는 지에 대해 다룰 예정이다. (개인적으로 엑스서브 하드웨어에 대한 논의도 하고 싶다.) 하지만 본 기사는 캐시의 크기가 왜 애플리케이션에 따라서 중요해지는 지, “tag RAM”이 뭘 의미하는 지 모르는 분들을 위한 기사이다.

 

Caching basics

시 스템 디자인에서 캐시의 역할을 이해하기 위해서는 소비자-생산자(혹은 클라이언트-서버) 모델로 CPU와 메모리 서스시스템부터 알아야한다. CPU는 생산자인 하드 디스크와 RAM이 제공하는 정보를 소비한다. 프로세스 기술과 프로세서 디자인의 발전덕택에, CPU는 고도의 효율로 정보의 소비가 가능해졌으며, 문제는 CPU의 클럭 사이클이 버스 클럭 사이클과 메모리보다 더 빠른 비율로 짧아진다는 데에 있다. 따라서, 메인메모리가 요구받은 데이터를 채울 수 있기 전까지 기다림을 의미하는 CPU 클럭 사이클 수치는 늘어나기 때문에, CPU 클럭속도가 늘어나면, 메모리는 CPU로부터 멀어지기만 한다.

Slower CPU

Clock Faster CPU Clock

이 렇게 서로 벌어지는 간격은 전체 시스템 퍼포먼스에 영향을 끼친다. CPU를 가구 공장 공방으로, 메인 메모리를 목재 하치장으로 생각해보라. 좀더 큰 트럭으로 모든 나무를 실어 나르더라도, 공방에서 주문을 채우는 시간은 더 길어지기만 할 것이다.

주: 공방과 하치장 모델로 캐시를 설명한 사람은 필자가 처음이 아니다. 제일 유명한 사례는 Thing King 게임[http://www.netjeff.com/humor/item.cgi?file=TheThingKing]이며, 필자는 이 게임을 페터 반 데어 린덴(Peter van der Linden)의 책[http://arstechnica.com/etc/books/deep-c.html]에서 처음 보았다.

이 사례에서 문제 해결의 한 가지 방법은, 시내의 좀더 소규모의 공방을 임대하여 최근에 들어온 나무 주문을 저장해두는 것이 있다. 이 공방은 원래 공방의 캐시로 작동하여, 여기에 원래 공방에서 필요로하는 것을 미리 비치해둘 수 있다. 물론, 원래의 공방은 더 크고 더 잘 돌아간다. 좀더 다양한 타입의 나무를 저장할 수 있기 때문에 어떤 주문이던지 간에 처리할 수 있다. 가까운 공방에 없는 나무가 필요할 때에는 원래 공방까지 가서 찾아와야하는데, 이경우는 특수한 주문이기 때문에 상당 시간을 기다려야한다는 단점이 있다. 주문한 사람은 대기실에서 담배나 피면서 오프라나 볼 수 밖에. 오프라를 보는 데 돈을 내야한다면 그 누가 좋아할까?

 

The Memory Hierarchy

이 해가 잘 됐으리라 확신한다. 하지만 우리의 소규모 공방은 캐시 분석의 첫 번째 단계(혹은 레벨 1-L1-캐시)에 불과하다. L1은 CPU에서 매우 빠르게 접근할 수 있기 때문에 CPU가 제일 많이 요구할법한 코드와 데이터를 저장하기에 매우 적당하다. (잠시 후에는, L1이 어떻게 CPU가 원하는 바를 “예측”할 수 있는 지에 대해 알아보겠다.) 빠른 접근 시간을 갖는 L1은 static RAM(SRAM)이라는 제일 고가이면서 제일 빠른 램으로 만들어진다. SRAM 메모리 셀은 네 개에서 여섯 개의 트랜지스터(DRAM은 셀당 하나의 트랜지스터를 갖는다.)를 갖기 때문에 가격이 비싸며, 따라서 L1이 커질 수록 시스템 전체 비용도 대폭 상승한다.

최 근에 나온 대부분의 CPU는 프로세서의 나머지 부분, 같은 실리콘 상에 L1을 입힌다. 공방 모델로 설명하자면, 원래 공방과 같은 동네에 작은 공방을 새로 설치하는 것과 마찬가지이다. 즉, CPU와 최대한 접근시켜서 더욱 빠른 속도를 얻는 것이다. 단점도 있다. L1이 프로세서에 좀더 가까워질 수록, 메인 메모리(혹은 지방의 공방)는 프로세어와 그만큼 멀어질 수 밖에 없다. 따라서, L1에 없는 데이터가 필요한 경우,(이와 같은 경우를 캐시 miss라고 부른다.) 메모리로부터 데이터를 얻는 시간은 오래 걸리며, 프로세서가 빠르다면 더더욱 오래걸리게 마련이다. 이경우 공방 모델로 비유하자면, 목재 하치장이 지방이나 다른 마을은 고사하고, 다른 나라에 있는 것이나 마찬가지이다. P4같은 높은 클럭속도를 갖는 프로세서는 오퍼레이션 하나를 완수하기 위해 메인 메모리로부터 데이터를 받을 때, 공방이 해외의 하치장에서 며칠 지난 뒤에 목재를 받는 것이나 마찬가지로 오래걸릴 수 있다.

아 래의 표를 보기 바란다. 이 표는 여러가지 타입의 메모리에서 레이턴시와 크기 정보를 보여준다. (수치가 최신은 아니다. 현재의 수치는 좀더 감소하였다.) L1 캐시와 메인 메모리 사이에서의 접근 시간에 대한 거대한 간격에 주목하기 바란다. 1GHz CPU에서 50 나노세컨드는 50번의 클럭 사이클을 낭비한다는 뜻이다.

여 기에 대한 해결책은, 좀더 많은 캐시를 다는 방법이 있다. 우선적으로 L1 자체를 늘리는 방법도 생각할 수 있겠지만, 위에서 밝힌 바와 같이 비용 상승을 고려해보면 오히려 L1의 캐시 크기를 제한해야한다. 공방 분석으로 보자면, 도심지에서의 임대비용은 교외보다 매우 비싸기 때문에 생산성을 높이기 위해 도심지에 공방을 따로 임대하는 데에는 한계가 있게 마련이다. 그러므로 공방의 크기를 적절히 해서 모든 비용과 수익이 균형이 맞도록 해야 최적의 비용으로 최대의 아웃풋을 낼 수 있다.

L1 을 늘리는 것보다 더 나은 해결책은 L1처럼 행동하면서 바로 옆 동네에 좀더 저렴하고 커다란 공방을 임대하는 방법이 있다. P4와 G4e와 같은 프로세서가 바로 이 방법을 써서, 메인 메모리와 L1 캐시 사이에 L2 캐시를 갖고 있다. L2 캐시는 보통 L1이 가진 모든 데이터에 별도의 데이터를 포함한다. 따라서 보통, L1 캐시가 L2 캐시의 부분집합이라고도 한다. L2는 L1에 플러스 알파가 더 있기 때문이다. 아래 그림에서 CPU가 현재 돌리고 있는 프로세스의 코드와 데이터는 붉은 셀로 나타나 있다. 푸른 셀은 현재 활성중인 프로세스와는 관련이 없다. (이 그림은, 로컬리티를 알게되면 좀더 잘 이해할 수 있다.)

하 드 디스크에서 파일을 페이징하는 것으로 시작하여 CPU의 모든 레지스터로 들어가는 과정을 캐시 계층(cache hierarchy)이라고 한다. CPU까지 위로 올라갈 수록 캐시는 점점 작아지고 빨라지며 구현에 대한 비용도 더 올라간다. 반대로 캐시 계층에서 아래로 내려갈 수록 좀더 커지고 저렴해지지만 더 느려진다. 계층에서 각기 갖고 있는 데이터는 보통 미러화 되기 때문에, L1 캐시에 있는 데이터는 L2와 메인 메모리까지 계속 복사하여 파일을 페이징한다. 따라서 계층의 각 레벨은 하위 레벨의 부분집합이다. 어떻게 서로 복사본을 유지하는 지에 대해서는 다음에 논의하도록 한다.

위 에서부터 보면, 각 레벨을 시스템의 각기 다른 부분이 통제하는 걸 알 수 있다. 데이터는 각기 다른 영역에 따라서 올라가고 내려가지만, 본 기사에서는 계층의 상위 레벨만 다루도록 한다. 또한 본 기사가 제시하는 수치는 최신 수치가 아니다. 이 수치는 필자가 에네시(Hennessy)와 패터슨(Patterson)의 책에서 발췌한(후반부의 참고 자료를 보기 바란다.) 부분이며, P4와 G4e 기반의 시스템의 좀더 구체적인 수치는 다음 기사에서 다룰 예정이다.

Leave a Reply