최근 수정 시각 : 2024-11-14 03:10:52

캐시 메모리

🖥️ 컴퓨터 부품 및 주변 기기
{{{#!wiki style="margin:0 -10px -5px; min-height:calc(1.5em + 5px);"
{{{#!folding [ 펼치기 · 접기 ]
{{{#!wiki style="margin: -6px -1px -11px"
<colbgcolor=#555>PC 주요 부품
<rowcolor=#fff> 프로세서 CPU · GPU · 레지스터 · 캐시 메모리
기억장치 주기억장치 : ROM · RAM( VRAM)
보조기억장치: 플래시 메모리( SSD · USB 메모리) · 자기 기억장치( HDD · 플로피 디스크 · 자기 테이프 · 외장 하드) · 광학 기억장치( ODD · CD · DVD · 블루레이 디스크)
'''메인보드 · 전원부 · {{{#!wiki 메인보드 · 쿨러 · 파워서플라이 · 케이스
PC 주변 기기
보안 TPM · 스마트카드
네트워크 · 입출력 휴먼 인터페이스 장치: 키보드 · 모니터 · 마우스 · 트랙볼 · 디지타이저 · 스타일러스 펜 · 사운드 카드 · 스피커 · 마이크 · HMD
입출력 장치: TV 수신 카드 · 프린터 · 네트워크 카드 · 캡처보드 · USB · 케이블
}}}}}}}}} ||

||<tablealign=right><width=400px> 파일:Cache-on-a-stick_module.jpg ||
1990년대까지 사용되었던 스틱형 캐시 메모리 모듈
파일:COAST_CPU.jpg
흰색 숫자 1은 인텔 소켓 7 타입의 초대 펜티엄 프로세서
흰색 숫자 2는 32 KB 용량의 온보드 캐시 메모리 모듈
흰색 숫자 3은 스틱형 캐시 메모리 모듈 슬롯


1. 개요2. 상세
2.1. 배경2.2. 캐시에 사용되는 메모리의 종류2.3. 멀티 레벨 캐시 메모리2.4. 작동 원리: 데이터 지역성2.5. 캐시 메모리의 목표2.6. 캐시 메모리 성능의 요소
2.6.1. 캐시 적중과 캐시 부적중
2.6.1.1. 캐시 부적중의 종류2.6.1.2. 응용 프로그램 특성별 캐시 적중률2.6.1.3. 캐시 부적중률의 중요성
2.6.2. 캐시 정책 및 알고리즘
2.6.2.1. 캐시 메모리의 논리적 기본 단위2.6.2.2. 캐시 배치 정책(cache placement policy)2.6.2.3. 캐시 포함 정책(cache inclusion policy)2.6.2.4. 캐시 교체 정책(cache replacement policy)2.6.2.5. 캐시 쓰기 정책(cache writing policy)
2.6.3. 캐시 일관성(cache coherence)2.6.4. 캐시 레이턴시
2.6.4.1. 캐시 메모리 접근 패턴2.6.4.2. 유효 레이턴시
2.6.5. 캐시 스루풋 및 대역폭
2.6.5.1. 유효 대역폭
2.6.6. 병렬 처리
2.7. 캐시 메모리의 최적화 기법2.8. 캐시 메모리의 종류2.9. 역사
2.9.1. CPU 캐시 메모리2.9.2. GPU 캐시 메모리
2.10. 캐시 메모리와 버퍼 메모리
3. 관련 자료4. 관련 문서

1. 개요

cache memory, hardware cache

컴퓨터 시스템의 성능을 향상시키기 위해 별도로 탑재된 캐시 전용 메모리.

레지스터, 메인 메모리와 함께 메모리 계층 구조의 전통적인 핵심 계층 중 하나이다. 프로그램에서 직접적으로 읽거나 쓸 수 없고 하드웨어의 메모리 관리 시스템이 내부적으로 제어한다. 대부분 프로그램은 한번 사용한 데이터를 재사용할 가능성이 높고, 그 주변의 데이터도 곧 사용할 가능성이 높은 데이터 지역성을 가지고 있다. 데이터 지역성을 활용하여 메인 메모리에 있는 데이터를 캐시 메모리에 불러와 두고, 프로세서가 필요한 데이터를 캐시 메모리에서 먼저 찾도록 하면 시스템 성능을 향상시킬 수 있다.

캐시 메모리의 가격은 21세기 현재도 메모리 소자 중에서 가장 비싼 편이며, 지난 20년간 가격이 3% 정도 떨어지는 데 불과했다.

2. 상세

2.1. 배경

프로세서의 클럭 속도가 매우 빨라짐에 따라 프로세서 밖에 있는 메인 메모리와의 속도 차이가 현저하게 증가했는데, 이 때문에 프로세서 클럭 속도를 아무리 올려도 메인 메모리에서 데이터를 빠르게 제공해 주지 못하여 전체 시스템 성능이 증가하기 어렵게 되었다. 폰 노이만은 1946년 그의 논문 "Preliminary Discussion of the Logical Design of an Electronic Computing Instrument" 에서 캐시 메모리의 필요성을 예견했다.

2.2. 캐시에 사용되는 메모리의 종류

메모리 기술은 주로 축전기를 사용하는 DRAM 플립플롭을 사용하는 SRAM으로 나뉘는데, DRAM은 가격이 싸고 용량 대비 크기가 작지만 속도가 느리고, SRAM은 속도는 빠르지만 가격이 매우 비싸고 용량 대비 크기가 크다는 단점이 있다. 그래서 DRAM을 사용자가 직접 장착하게 하는 대신, CPU와 DRAM 사이에 SRAM을 별도로 두어서 DRAM의 데이터를 직접 접근하는 것보다는 빠르게 접근할 수 있도록 한다.

현행 CPU 내부 캐시 메모리는 전력 소모, 동작 속도, 면적 등을 고려하여 6T SRAM[1] 또는 8T SRAM[2] 중 하나를 주로 사용한다. CPU 온다이 캐시 메모리를 제외한 사용처에서는 DRAM, 심지어 플래시 메모리도 캐시로 활용될 수 있다. 플래시 메모리 기반 SSD에서 지원하는 SLC 캐싱이 대표적인 예시.

2.3. 멀티 레벨 캐시 메모리

시스템에 장착된 캐시의 용량과 성능이 점점 증가하면서 캐시로 사용되는 메모리가 추가되었는데, 이것을 순서대로 L(Level) 1, L2, L3, ... 라고 호칭한다.

이 레벨 숫자가 낮을수록 CPU 코어와 가까워서 속도가 빠르지만 용량이 적은 편이다. 가장 낮은 레벨은 L1 캐시 메모리이며 명령어 캐시와 데이터 캐시로 나뉘어져 있다. 레벨 숫자가 올라가면 용량이 증가하지만 CPU 코어와의 거리가 멀어 속도가 L1보다 느려진다. L2와 L3 캐시 메모리가 해당되며 L1와 L2 캐시 메모리는 CPU 코어[3]마다 존재하지만 L3 캐시 메모리는 L1, L2 캐시메모리보다 용량이 큰 대신에 하나 밖에 없고 모든 CPU 코어가 공용으로 사용한다. L3 캐시 메모리가 마지막 레벨의 캐시 메모리일 경우, L3 캐시 메모리를 LLC라고 부르기도 한다.

2.4. 작동 원리: 데이터 지역성

캐시 메모리는 데이터 지역성(locality)의 원리를 이용한다. 데이터 지역성은 시간 지역성(temporal locality), 공간 지역성(spatial locality), 순차적 지역성(sequential locality)으로 나뉘는데, 시간 지역성이란 for나 while 같은 반복문에 사용하는 조건 변수처럼 한번 참조된 데이터는 잠시 후에 또 참조될 가능성이 높다는 것이고, 공간 지역성이란 A[0], A[1]과 같은 데이터 배열에 연속으로 접근할 때 참조된 데이터 근처에 있는 데이터가 잠시 후에 사용될 가능성이 높다는 것이며, 순차적 지역성이란 분기(branch)가 발생하는 비순차적 실행이 아닌 이상 명령어들이 메모리에 저장된 순서대로 실행하는 특성을 이용한 원리로 순차적일 수록 다음 순서의 데이터가 사용될 가능성이 높다.

쉽게 예를 들자면 무지하게 지랄맞고 부지런한 상사가 한 시간 전에 작년과 금년 재무 결산 보고서를 가져오라고 했을 때, 어차피 순서대로 정리되어 있는 내년과 내후년 재무 결산 보고서도 가져오라고 할지 모르니까 그것도 묶음째로 근처에 준비해 놓는 식이다. 여기에 더해 상사가 오늘 아침에 작년 재무 결산 보고서를 요청했다면, 오늘 하루 동안 그 보고서를 여러 번 더 요청할 가능성이 높으니, 그 보고서를 책상 위에 계속 놓아두는 것이라고도 할 수 있다.

또 다른 예로는 캐시는 지갑이라고 생각하면 된다. 지갑 혹은 주머니가 없다면 우리가 현금(cash)이 필요할 때마다 매번 은행이나 ATM에 가야 할 것이다. 이는 당연히 매우 귀찮고 시간도 많이 걸린다. 하지만 우리가 현금을 지갑에 넣고 다님으로써 시간을 절약할 수 있다.

CPU가 메모리에 데이터를 요청할 때, DRAM에 접근하기 전에 일단 캐시 메모리에 접근하여 데이터 존재 여부를 확인한다. 캐시 메모리는 메인 메모리인 DRAM보다는 그 사이즈가 매우 작아서 데이터를 모두 저장할 수 없다. DRAM이 보통 수 GB 단위 정도인데 인텔 i5, i7에 들어가는 캐시 메모리는 작게는 수 KB ~ 많게는 수 MB 정도이다. 캐시 메모리는 DRAM의 데이터 일부를 가지고 있다가 CPU가 요청한 데이터가 캐시 메모리에 없으면 CPU를 잠시 기다리게 한 후 DRAM에서 해당 데이터를 가져온 후 CPU에게 넘겨 준다. CPU는 캐시의 존재를 알고 있지만, 그 위에서 실행되는 프로그램은 메인 메모리의 주소만 지정하거나 캐시 적중률을 위해 힌트를 줄 수는 있어도[4], 프로그래머가 캐시 메모리를 직접 지정할 수는 없다. 이렇게 그 존재가 외부에 드러나지 않기 때문에 캐시 메모리는 CPU에 투명(transparent)하다고 한다. 투명하지 않은 작은 온칩 메모리는 scratchpad memory라고 부른다.

캐시 메모리에 데이터를 저장할 때 공간 지역성을 최대한 활용하기 위해 해당 데이터뿐만 아니라 옆 주소의 데이터도 같이 가져와 미래에 쓰일 것을 대비한다. CPU의 경우, DRAM에는 프로그램을 수행하는 명령어(instruction)와 그 명령이 실행되는 데이터(data)가 함께 들어 있는데, 명령어는 읽기만 하고 데이터는 읽기와 쓰기를 동시에 하므로 캐시 메모리 내에 이들을 각각 명령어 캐시 메모리(instruction cache)와 데이터 캐시 메모리(data cache)에 저장한다.

보통 L1 캐시 메모리에는 명령어 캐시와 데이터 캐시 메모리가 따로 있고, L2 캐시 메모리는 딱히 둘의 구분 없이 하나의 캐시 메모리로 구성된다. L1 캐시 메모리는 CPU에 직접 데이터를 공급해 주기 때문에 빠른 접근 지연 시간(access latency)이 매우 중요한데, 명령어는 보통 공간 지역성이 높고 데이터는 보통 시간 지역성이 높다. 이 둘을 나누어 서로 다른 지역성을 이용할 수 있다. 또한 명령어와 데이터를 동시에 읽어올 수 있게 함으로써 CPU의 파이프라이닝 성능을 향상시킬 수 있다.

2.5. 캐시 메모리의 목표

  • 캐시 적중률의 최대화 & 부적중률(不的中率)의 최소화
  • 캐시 레이턴시의 최소화
  • 캐시 대역폭의 최대화
  • 캐시 정책 및 알고리즘의 최적화
  • 캐시 부적중에 따른 패널티의 최소화
  • 데이터 일관성 보장
  • 데이터 일관성에 따른 오버헤드 최소화

캐시 메모리는 궁극적으로 성능 향상을 목적으로 등장한 전용 메모리이다. 성능에 영향을 주는 요소에 대한 자세한 설명은 아래 항목에 후술.

2.6. 캐시 메모리 성능의 요소

캐시 메모리의 스펙을 따질 때 십중팔구 캐시 메모리 용량만 보는 경우가 많다. 제조사가 캐시 메모리 관련 스펙을 표기할 때 용량만 표기하기 때문. 대부분 DRAM으로 구성된 메인 메모리와 마찬가지로 레이턴시, 스루풋, 병렬 처리 능력이 캐시 메모리의 성능을 결정하는 주요 지표이지만, 수치화할 수 있는 적중률(반대로는 적중 실패율), 수치화하기 어려운 각종 캐시 정책(알고리즘)들과 캐시 일관성 프로토콜들도 캐시 메모리의 성능에 영향을 주므로 이론적인 성능과 실제 성능의 괴리감이 메인 메모리보다 더 클 수 있다.

2.6.1. 캐시 적중과 캐시 부적중

CPU가 데이터를 요청하여 캐시 메모리에 접근했을 때 캐시 메모리가 해당 데이터를 가지고 있다면 이를 '캐시 적중(cache hit)'이라고 부르고, 해당 데이터가 없어서 DRAM에서 가져와야 한다면 '캐시 부적중(cache miss)'이라 부른다. 캐시 부적중 할 경우의 처리 방법은 캐시 정책에 따라 다르며, 데이터를 읽어 오는 시점으로 사용하기도 한다. 캐시 적중의 정도를 나타내는 지표가 캐시 적중률(cache hit ratio)인데 퍼센트 단위(%)로 표현하려면
[math(\frac{(캐시\, 적중\, 횟수)}{(캐시\, 적중\, 횟수) + (캐시\, 부적중\, 횟수)}\times 100 (\%))]

또는 [math(\frac{(캐시 적중 횟수)}{(전체 요청 및 접근 횟수)}\times 100 (\%))]으로, 당연히 높을수록 좋다. 반대 개념인 캐시 부적중률(cache miss ratio)은 [math(1 - (캐시 적중률))]이다.
2.6.1.1. 캐시 부적중의 종류
캐시 부적중(miss)이 나는 경우는 대부분의 경우 3가지로 나눌 수 있는데
  • compulsory miss(또는 cold miss): 해당 메모리 주소를 처음 불렀기 때문에 나는 미스. 예를 들어 프로그램을 새로 켜거나 하는 경우 발생한다. 간혹 사용할 데이터를 미리 프리페치하는 경우가 아닌 이상 사실상 예방이 불가능한 캐시 미스지만, 전체 컴퓨터 이용 시간에 비하면 굉장히 드물게 나는 미스 유형이라 전체적인 성능에 영향을 미치는 정도는 작다.
  • conflict miss: 캐시 메모리에 A 데이터와 B 데이터를 저장해야 하는데, A와 B가 같은 캐시 메모리 주소에 할당돼서 나는 캐시 미스다. 예를 들어 내가 휴대폰과 따뜻한 커피 캔은 항상 외투 오른쪽 주머니에만 넣는 습관이 있다고 하자. 평상시에는 오른쪽 주머니에 휴대폰만 넣고 다니는데, 어느 날 친구에게 커피 캔을 받아서 잠시 휴대폰을 가방 속에 넣어두고 커피 캔을 오른쪽 주머니에 넣었다. 이때 휴대폰을 오른쪽 주머니에서 찾으려고 한다면 그때 conflict miss가 난다. direct mapped cache에서 가장 발생 빈도가 높고, n-associative cache에서 n이 커질수록 발생 빈도가 낮아지지만 대신 n이 커질수록 캐시 속도가 느려지고 파워도 많이 먹는다.
  • capacity miss: 캐시 메모리에 공간이 부족해서 나는 캐시 미스. 위의 conflict miss는 캐시에 공간이 남아도는데도 불구하고 주소 할당 때문에 나는 미스지만, capacity miss는 주소 할당이 잘되어 있더라도 공간이 부족하면 나는 미스다. 캐시 공간이 작아서 벌어지는 일이므로 캐시 크기를 키우면 해결되지만, 캐시 크기를 키우면 캐시 접근 속도가 느려지고 파워를 많이 먹는다는 단점이 생긴다.

만약 대부분의 메모리 요청이 캐시 미스라면 차라리 캐시 메모리를 안 쓰는 게 더 빠르다. 하지만 다행히도 캐시 적중 실패율이 단순 작업 기준으로 평균 10% 안쪽이기 때문에 캐시 메모리를 통해 컴퓨터 시스템의 평균 성능을 크게 향상시킬 수 있으며 클럭 속도, 코어 개수와 함께 컴퓨터 성능에서 매우 큰 비중을 차지한다. 그러나 많은 사람들이 캐시 메모리에 대해 잘 모르며 실제 캐시 메모리가 없이 클럭 속도가 더 높은 CPU가 클럭 속도는 낮지만 캐시 메모리가 있는 CPU보다 대체로 더 나쁜 성능을 보여준다. 셀러론이 저렴한 데에는 다 이유가 있다

어떤 이는 컴퓨터에 사용된 도박의 원리라고 하기도 하는데, 이는 캐시 메모리의 작동 원리가 도박에서 돈을 거는 것과 유사하기 때문이다. 캐시 적중 실패율이 낮으면 도박에 질 확률이 낮다는 의미이기도 하므로 대부분 이기는 도박이라 할 수 있다.
2.6.1.2. 응용 프로그램 특성별 캐시 적중률
파일:intel-memory-cache-hits-synthetic-original-image-size.jpg
렌더링 전문 작업에서의 캐시 적중률

파일:intel-memory-cache-hits-gaming-original-image-size.jpg
게임에서의 캐시 적중률

위의 슬라이드 이미지는 인텔이 2019년 E3에서 발표했던 자료로,[5] 렌더링 작업의 경우 처리 과정이 게임보다 비교적 단순하기 때문에 CPU 캐시 적중률이 높게 측정된다. 반면에, 게임은 렌더링 작업과는 다르게 GPU에게 지시하는 렌더링 명령뿐만 아니라 프레임 업데이트, 물리 연산, 애니메이션 연산, 사운드 연산, 입출력, 네트워크 등 복합적으로 처리되는 과정이라서 CPU 캐시 적중률이 생각보다 높지 않다. 그렇기 때문에 게임이 렌더링 작업보다 CPU 캐시 메모리 용량에 더 민감한 편이다.
그래놓고 다음해에 5600X에게 다 발려놓고, 12세대 때는 5800X3D에게 또 발려 버렸다
물론, '렌더링 전문 작업'과 '게임'이라는 2가지 대분류만 구분해서 비교할 때 대체로 그러한 경향이라는 것이지, 같은 전문 작업이라도 렌더링이 아닌 워크로드일 경우 CPU 캐시 적중률이 상이할 수 있으며, 게임 내에서도 게임 플레이 로직의 복잡도나 메모리 최적화 수준 혹은 기본적인 요구 사양 수준에 따라 CPU 캐시 적중률이 상이할 수 있다.
2.6.1.3. 캐시 부적중률의 중요성
캐시 적중에 관한 문제는 적중률을 기준으로 판단하는 경우가 많지만, 학계 및 관련 업계에서는 캐시 적중률보다는 캐시 '부적중률'에 초점을 맞춘다. 가령, 캐시 적중률이 98%에서 99%로 증가되었을 때, 적중률 기준으로 계산하면 겨우 약 1%밖에 향상되지 않은 것으로 해석할 수 있지만, 부적중률 기준으로 계산하면 2%에서 1%로 무려 50%나 감소된 것으로도 해석할 수 있기 때문.

캐시 적중률 98%와 99%의 차이가 별거 아닌 것처럼 보일지라도, 한 번이라도 캐시 부적중 되면 캐시 메모리보다 느린 메인 메모리로 가야 하는 시간적인 페널티뿐만 아니라, 지연된 시간으로 인한 전체적인 평균 대역폭 페널티까지 연쇄적으로 발생하기에 부적중률에 민감할 수밖에 없다.

2.6.2. 캐시 정책 및 알고리즘

캐시 메모리 성능 향상에 있어서 적절한 캐시 정책 및 알고리즘을 취해야 유효 레이턴시를 최소화하면서 유효 대역폭을 끌어 올릴 수 있다.
2.6.2.1. 캐시 메모리의 논리적 기본 단위
일반적인 캐시 메모리의 물리적 구조는 그냥 수많은 SRAM 셀들이 2차원 또는 3차원으로 배열된 모습일 뿐이다. 하지만, 캐시 메모리의 용량이 메인 메모리에 비해 매우 적어서 성능 향상을 목적으로 효율적으로 관리하기 위해서는 논리적 구조로써 파악할 필요가 있다.

| 캐시 엔트리 |<|1><-3><height=32><tablewidth=100%>
| 캐시 태그 |<width=20%> 태그 비트 ||<width=10%> 유효 비트 ||
||<|1><-1><height=32><width=70%> 캐시 블록 ||

  • 캐시 엔트리
    • 캐시 블록 : 데이터 그룹 단위로, 캐시 메모리에 담겨질 실질적인 데이터가 이곳에 있다.
    • 캐시 태그
      • 태그 비트 : 캐시 블록의 고유 식별값으로, 실질적인 데이터가 담겨져 있지 않지만 그 데이터들을 식별하기 위해 추가로 할당되어 있다.
      • 유효 비트 : 해당 캐시 블록의 올바른 데이터가 있는지 판별해 주는 플래그 비트로, 캐시 태그에 포함되어 있다.

캐시 엔트리는 캐시 메모리의 데이터를 구분하는 논리적인 최소 단위로, 이들이 모여서 캐시 메모리 전체를 구성한다. 흔히 몇 MB 캐시 메모리라는 것은 정확히 따지면 몇 MB만큼의 실질적인 데이터를 담을 수 있는 캐시 메모리를 의미하는데, 다시 말해서 캐시 태그에 할당된 용량을 제외한 용량이라는 뜻이다. 따라서, 캐시 메모리의 실제 용량은 캐시 태그에 할당된 용량만큼 더 추가된 용량인 셈이다. 다만, 캐시 태그가 실질적인 데이터가 아니기 때문에 일종의 오버헤드(overhead)로 취급되며, 식별 목적으로 쓰이므로 일반적으로 캐시 블록에 비하면 매우 작은 용량만 할당된다. 이 캐시 엔트리들을 어떻게 배치할 것인지는 캐시 배치 정책에 따른다.
2.6.2.2. 캐시 배치 정책(cache placement policy)
흔히 캐시 사상(mapping) 구조라고도 부르는 정책으로, 여러 캐시 엔트리들을 배치하는 방법을 설명하는 정책이기도 하다.
  • Direct Mapped Cache
    {{{#!wiki style="word-break: keep-all"
캐시 라인 n개
{{{#!wiki style="margin: -6px -1px -11px" 캐시 블록
}}} ||<|5> ||<|5>캐시 라인 수 : [math(n)]개
캐시 블록 수 : [math(n)]개
캐시 블록 용량 : [math(a)] Byte
캐시 메모리 용량 : [math(b \times 2^{c} = 2^{\log_2 b} \times 2^{c} = 2^{{(\log_2 b)}+{c}} = n×a)] Byte
메인 메모리 용량 : [math(d \times 2^{e} = 2^{\log_2 d} \times 2^{e} = 2^{{(\log_2 d)}+{e}})] Byte
메인 메모리 블록 수 : [math(2^{{(\log_2 d)}+{e}-{a}})]개
메인 메모리 주소 비트 : [math(\lceil(\log_2 d)\rceil +e)] bit
인덱스 필드 : [math(\lceil(\log_2 n)\rceil)] bit
블록 오프셋 필드 : [math(\lceil(\log_2 a)\rceil)] bit
태그 필드 : [math(\lceil(\log_2 d)\rceil + e - \lceil(\log_2 n)\rceil - \lceil(\log_2 a)\rceil)] bit
||
{{{#!wiki style="margin: -6px -1px -11px" 캐시 블록
}}} ||
[math(\vdots)]
{{{#!wiki style="margin: -6px -1px -11px" 캐시 블록
}}} ||
{{{#!wiki style="margin: -6px -1px -11px" 캐시 블록
}}} ||
{{{#!wiki style="margin: -6px -1px -11px" 인덱스 필드
[math(\lceil(\log_2 n)\rceil)] bit
블록 오프셋 필드
[math(\lceil(\log_2 a)\rceil)] bit
}}} ||
}}} 파일:external/www.cs.fsu.edu/F7.5.gif
가장 기본적인 캐시 배치 정책으로, 직역해서 '직접 사상(寫像) 방식'이라고도 한다. DRAM의 여러 주소가 캐시 메모리의 한 주소에 대응되는 다대일(n:1) 방식이다. 그림을 참고해서 간단히 설명하자면, 메인 메모리의 공간이 32개(00000₂부터 11111₂)이고, 캐시 메모리의 공간이 8개(000₂부터 111₂)이면, 메인 메모리의 주소가 00000₂, 01000₂, 10000₂, 11000₂인 곳의 데이터를 캐시 메모리의 주소가 000₂인 곳에만 읽고 쓰는 방식이다. 이때 000₂을 인덱스 필드(Index Field), 인덱스를 제외한 나머지 비트 00₂, 01₂, 10₂, 11₂을 태그 필드(Tag Field)라 하고, 기본적으로 태그 비트와 인덱스 비트 뒤에 데이터를 저장하는 데이터 필드(Data Field)가[6] 붙어있는 구조를 갖고 있다.
Direct Mapped Cache의 작동 방식은 대략 다음과 같은 식이다. 캐시 메모리가 비워진 상태로 CPU가 메인 메모리의 00000₂ 주소의 데이터를 두 번 연속해서 읽는다고 하자. CPU는 먼저 캐시 메모리를 뒤적이는데 요청한 주소가 00000₂이므로 캐시 메모리의 주소가 000₂인 곳을 확인한다. 확인 후 아무것도 없는 것을 확인하고 직접 메인 메모리의 00000₂주소를 참조하여 데이터를 읽어 온다. 이때 또 쓸지도 모르니까 캐시 메모리의 000₂인 공간에 00₂ 태그 비트와 아까 읽은 메인 메모리 00000₂의 데이터를 저장해 놓는다. 그다음 바로 같은 동작을 수행하면서 똑같이 캐시 메모리의 000₂ 인 곳을 확인하는데 이번엔 데이터가 들어있으니 그 데이터가 CPU가 요구한 주소의 데이터와 일치하는지 태그 비트를 비교하는 검사를 한 뒤 태그 비트마저 일치하면 캐시 메모리에서 데이터를 가져온다.
간단하고 빠르지만 대신 약점이 굉장히 큰데, conflict miss 문제가 굉장히 큰 방식이다. 직관적으로 생각해서 위 그림의 회색 데이터는 하나도 저장할 필요가 없는데 주황색 데이터 중 2개 이상을 동시에 저장해야 하는 일이 생기면 굉장히 골치 아플 것임을 알 수 있다. 캐시 메모리의 공간 활용도가 떨어지는 셈이다. conflict miss가 심한 문제점 때문에 현대 CPU에서는 어지간하면 채택되지 않는 편이다.
  • Fully Associative Cache
    {{{#!wiki style="word-break: keep-all"
캐시 라인 n개
{{{#!wiki style="margin: -6px -1px -11px" 캐시 블록
}}} ||<|1><-2><height=32>
| 캐시 엔트리 1 | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32> [math(\cdots)] ||<|1><-2><height=32>
| 캐시 엔트리 (n-1) | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32>
| 캐시 엔트리 n | 캐시 태그 || 캐시 블록 ||
||
캐시 라인 수 : [math(n)]개
캐시 블록 수 : [math(n)]개
캐시 블록 용량 : [math(a)] Byte
캐시 메모리 용량 : [math(b \times 2^{c} = 2^{\log_2 b} \times 2^{c} = 2^{{(\log_2 b)}+{c}} = n×a)] Byte
메인 메모리 용량 : [math(d \times 2^{e} = 2^{\log_2 d} \times 2^{e} = 2^{{(\log_2 d)}+{e}})] Byte
메인 메모리 블록 수 : [math(2^{{(\log_2 d)}+{e}-{a}})]개
메인 메모리 주소 비트 : [math(\lceil(\log_2 d)\rceil +e)] bit
인덱스 필드 : (필요 없음)
블록 오프셋 필드 : [math(\lceil(\log_2 a)\rceil)] bit
태그 필드 : [math(\lceil(\log_2 d)\rceil + e - \lceil(\log_2 a)\rceil)] bit
{{{#!wiki style="margin: -6px -1px -11px" 블록 오프셋 필드
[math(\lceil(\log_2 a)\rceil)] bit
}}} ||
}}}
완전 연관 사상 방식이라고도 부르며, 쉽게 설명하면 비어있는 캐시 메모리가 있으면 그냥 마음대로 주소를 저장하는 방식이다. 즉 저장할 때는 크게 알고리즘이 필요 없어서 간단하면서도 캐시 메모리 공간 활용도가 높지만, 찾을 때가 문제다. 어떠한 조건이나 규칙이 없으니 모든 캐시 블록에서 원하는 데이터가 있는지 일일이 찾아서 검사해야 한다. 이를 위해 CAM(Content Addressable Memory)라는[7] 특수한 형태의 메모리 구조를 사용하게 되는데, 가격이 비싼 점이 흠이다.
비용 문제가 커서 이용하는 곳이 없을 것 같지만, CPU 내부 여러 계층의 TLB(Translation Lookaside Buffer)들 중 L1 명령어 TLB가 이 방식에 채택되는 편이다.
  • Set Associative Cache
    {{{#!wiki style="word-break: keep-all"
캐시 세트 m개 × 캐시 세트당 캐시 라인 n개
{{{#!wiki style="margin: -6px -1px -11px" 캐시 블록
}}} ||<|1><-2><height=32>
| 캐시 엔트리 1 | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32> [math(\cdots)] ||<|1><-2><height=32>
| 캐시 엔트리 (n-1) | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32>
| 캐시 엔트리 n | 캐시 태그 || 캐시 블록 ||
||
}}} ||
{{{#!wiki style="margin: -6px -1px -11px" 캐시 블록
}}} ||<|1><-2><height=32>
| 캐시 엔트리 1 | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32> [math(\cdots)] ||<|1><-2><height=32>
| 캐시 엔트리 (n-1) | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32>
| 캐시 엔트리 n | 캐시 태그 || 캐시 블록 ||
||
}}} ||
[math(\vdots)]
{{{#!wiki style="margin: -6px -1px -11px" 캐시 블록
}}} ||<|1><-2><height=32>
| 캐시 엔트리 1 | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32> [math(\cdots)] ||<|1><-2><height=32>
| 캐시 엔트리 (n-1) | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32>
| 캐시 엔트리 n | 캐시 태그 || 캐시 블록 ||
||
}}} ||
{{{#!wiki style="margin: -6px -1px -11px" 캐시 블록
}}} ||<|1><-2><height=32>
| 캐시 엔트리 1 | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32> [math(\cdots)] ||<|1><-2><height=32>
| 캐시 엔트리 (n-1) | 캐시 태그 || 캐시 블록 ||
||<|1><-2><height=32>
| 캐시 엔트리 n | 캐시 태그 || 캐시 블록 ||
||
}}} ||
캐시 세트 수 : [math(m)]개
캐시 세트당 캐시 라인 수 : [math(n)]개
캐시 블록 수 : [math((m×n))]개
캐시 블록 용량 : [math(a)] Byte
캐시 메모리 용량 : [math(b \times 2^{c} = 2^{\log_2 b} \times 2^{c} = 2^{{(\log_2 b)}+{c}} = n×m×a)] Byte
메인 메모리 용량 : [math(d \times 2^{e} = 2^{\log_2 d} \times 2^{e} = 2^{{(\log_2 d)}+{e}})] Byte
메인 메모리 블록 수 : [math(2^{{(\log_2 d)}+{e}-{a}})]개
메인 메모리 주소 비트 : [math(\lceil(\log_2 d)\rceil +e)] bit
세트 인덱스 필드 : [math(\lceil(\log_2 m)\rceil)] bit
블록 오프셋 필드 : [math(\lceil(\log_2 a)\rceil)] bit
태그 필드 : [math(\lceil(\log_2 d)\rceil + e - \lceil(\log_2 m)\rceil - \lceil(\log_2 a)\rceil)] bit
{{{#!wiki style="margin: -6px -1px -11px" 세트 인덱스 필드
[math(\lceil(\log_2 m)\rceil)] bit
블록 오프셋 필드
[math(\lceil(\log_2 a)\rceil)] bit
}}} ||
}}}
집합 연관 사상 방식이라고도 부르며, direct mapped cache의 장점과 fully associative cache의 장점을 섞었다고 할 수 있는 가장 나중에 나온 방식이다. 특정 행을 지정해서 그 행 안의 어떤 열이든 비어있으면 저장하는 방식이다. 당연히 direct에 비해서는 검색은 오래 걸리지만 저장이 빠르며, associative에 비해 저장이 느린 대신 검색이 빠른 중간적인 특징이라고 할 수 있다. 현대 CPU 모든 계층의 캐시 메모리에서 채택되는 방식이며, CPU-Z의 계층별 캐시 메모리 용량 정보 옆에 표기된 n-way가 이 방식을 의미한다. 단, 표기해야 할 캐시 메모리 용량 정보가 많은 CPU일 경우, n-way 항목이 생략된다. CPU-Z VALIDATOR 사이트를 통해 확인할 수 있다.
참고로, 두 방식을 혼합한 방식이기 때문에 direct mapped cache는 1-way set associative cache, fully associative cache는 (전체 캐시 라인 수)-way set associative cache로도 표현할 수 있다.
  • 예시) 인텔 코어 i9-9900K + DDR4 SDRAM 128 GB인 메인 메모리
    • L3 캐시 메모리 데이터 가용량 : 16 MB (= 224 Byte)
      • L3 캐시 블록 용량 : 64 Byte (= 26 Byte)
      • L3 캐시 배치 정책 : 16-way Set Associative
      • L3 캐시 세트당 캐시 라인의 수 : 16개 (= 24개)
      • L3 캐시 블록의 수 : 262,144개 (= 218개)
      • L3 캐시 세트의 수 : 16,384개 (= 214개)
    • 메인 메모리 주소 비트 : 37-bit ([math(\because)] 128 GB = 237 Byte)
      • L3 캐시 블록 오프셋 비트 : 6-bit ([math(\because)] 64 = 26)
      • L3 캐시 세트 인덱스 비트 : 14-bit ([math(\because)] 16,384 = 214)
      • L3 캐시 태그 비트 : 17-bit ([math(\because)] 37 - (6 + 14) = 17)
    • L3 캐시 메모리 오버헤드 : 3.3203125%
    • L3 캐시 메모리 실제 용량 : 16.53125 MB
2.6.2.3. 캐시 포함 정책(cache inclusion policy)
  • inclusive 정책
  • exclusive 정책
  • NINE(non-inclusive non-exclusive) 정책
2.6.2.4. 캐시 교체 정책(cache replacement policy)
  • random 정책
  • FIFO(first in, first out) 정책
  • LRU(least recently used) 정책
  • LFU(least frequently used) 정책
2.6.2.5. 캐시 쓰기 정책(cache writing policy)
  • write-through 정책
  • write-back(write-behind) 정책
  • write allocate(fetch on write) 정책
  • no-write allocate(write-no-allocate 또는 write around) 정책

2.6.3. 캐시 일관성(cache coherence)

캐시 일관성은 공유 메모리 시스템에서 각각의 CPU 코어들이 가진 로컬 캐시 메모리 간의 일관성을 의미한다. 코어별로 자신만의 로컬 캐시 메모리를 가지고 다른 여러 코어들과 캐시 메모리를 공유하고 있을 때, 캐시의 갱신으로 인한 데이터 불일치 문제가 발생할 수 있는데, 이러한 현상을 효과적으로 막기 위해 여러 종류의 일관성 프로토콜이 등장하게 되었다.

캐시 일관성이 확보되면 MLP(memory-level parallelism) 능력이 향상되어 유효 레이턴시를 줄일 수 있고, 캐시 미스되더라도 뛰어난 MLP 능력 덕분에 레이턴시 페널티를 줄일 수 있다.
  • 소프트웨어 방식
  • 하드웨어 방식
    • 디렉터리 기반 구조
    • 스누핑 구조

2.6.4. 캐시 레이턴시

캐시 메모리의 레이턴시는 데이터 요청부터 처리 시작하기까지의 걸리는 시간으로, 메인 메모리의 레이턴시와 본질적으로 같다. 레이턴시의 중요도가 떨어졌던 메인 메모리와는 다르게, 중요도가 높다. CPU에 더 가까운 메모리 구조이기 때문. 멀티 레벨 캐시 메모리 구조를 채택하고 있는 CPU의 경우 같은 캐시 메모리라도 상위 레벨일수록 레이턴시가 짧고 더욱 민감해지는 특징을 지니고 있다.

또한, 캐시 메모리 용량이 클수록 캐시 적중률이 높아지지만 레이턴시가 늘어난다는 단점이 있다.
2.6.4.1. 캐시 메모리 접근 패턴
캐시 메모리 접근 패턴은 캐시 메모리에 담겨진 데이터를 어떤 방식으로 접근하는지를 구분한 개념으로, 접근 패턴에 따른 레이턴시 편차가 나타난다. 데이터 지역성에 따라 순차적일수록 캐시 적중률이 높고 레이턴시가 짧지만 랜덤할수록 캐시 적중률이 떨어지고 레이턴시가 길어진다. 현대 프로세서는 레이턴시라는 약점을 감추는 기술이 고도화되어 있기 때문에 한 가지의 접근 패턴만으로는 레이턴시를 종합적으로 가늠하기 어렵다. 접근 패턴 구분없이 한 가지 접근 패턴을 기준으로만 측정된 AIDA64 Cache & Memory Benchmark의 레이턴시값을 맹신해서는 안 되는 이유이기도 하다.
2.6.4.2. 유효 레이턴시
데이터에 접근하기까지의 걸리는 시간을 의미하는 레이턴시는 엄밀히 따지면 캐시 적중 되었을 경우를 전제로 하는 개념이다. 하지만 실제 캐시 메모리를 전체적으로 보면 캐시 적중 되지 않은 데이터도 혼재되어 있는데다 분기 예측기(branch predictor) 덕분에 프리페치(prefetch)가 발전되면서 분기 예측 없이 인출(fetch)했을 때보다 더 높은 캐시 적중률을 보여주다 보니 괴리가 발생할 수밖에 없는데, 이러한 특성을 반영한 실질적인 레이턴시라고 보면 된다.

특정 접근 패턴에서 레이턴시가 1 ns일 때 10개의 스레드가 동시에 캐시 메모리에 접근하여 캐시 적중되었을 경우 전체적으로 보면 레이턴시가 1 ns로 보이겠지만, 스레드 1개가 캐시 미스되어 레이턴시 페널티를 받을 경우 전체적으로 보면 모두 적중했을 때보다 더 길게 보일 수 있다. 반대로 분기 예측까지 동원되면 분기 예측 없이 수행했을 때보다 캐시 적중률을 더 높일 수 있으므로 레이턴시 페널티를 덜 받게 됨으로써 전체적인 레이턴시가 짧아지는 것처럼 보여진다. 이러한 특성을 활용하여 캐시 메모리 용량 증가에 따른 레이턴시 증가를 어느 정도 감출 수 있다.

2.6.5. 캐시 스루풋 및 대역폭

캐시 메모리의 스루풋은 일정 시간 단위의 데이터 처리량으로, 메인 메모리의 스루풋과 같은 개념이다. 실제 캐시 메모리는 여러 채널 및 여러 스레드를 동원하여 처리되므로 사실상 대역폭으로 봐도 무방하다.
2.6.5.1. 유효 대역폭
유효 레이턴시와 마찬가지로, 캐시 대역폭에도 유효 대역폭이 있다. 메인 메모리의 유효 대역폭처럼 병목 현상에 따른 부분도 있지만, 캐시 메모리에는 적중률 개념도 있기 때문에 적중률까지 고려한 대역폭이라고 보면 된다.

2.6.6. 병렬 처리

병렬 처리는 멀티 프로세서 또는 멀티코어 프로세서에 따른 SMT 하이퍼스레딩 같은 코어당 2-way SMT이 등장하면서 나타난 성능 요소로, 캐시 메모리 레벨에서의 병렬 처리 능력이기 때문에 memory-level parallelism, 줄여서 MLP라고도 부른다. 싱글코어 싱글스레딩 CPU인 시절에는 하나의 스레드만 캐시 메모리에 접근하므로 싱글스레드 기준의 레이턴시와 대역폭만 고려했으나, 2000년대 이후 일반 가정용 PC에도 멀티스레딩 시대가 오면서 멀티스레드 기준의 레이턴시와 대역폭으로 고려해야 정확하게 가늠할 수 있다. 일반적으로 스레드 개수가 많을수록 더 많은 데이터를 접근할 수 있으므로 그만큼 처리량도 많아지니, 캐시 메모리 성능이 어느 정도까지는 대체로 높게 나타난다.

MLP가 가능해지면서 캐시 메모리의 목표 중 하나인 '캐시 미스에 따른 레이턴시의 최소화'에 결정적인 요소가 되었다. 쉽게 말해서 일련의 작업이 주어졌을 때 1명이 실수해도 도와줄 사람들이 많을 수록 신속하게 수습할 수 있는 것과 비슷하다고 보면 된다. 단, 일정 용량 이상에 도달하면 캐시 메모리 성능이 정체되거나 오히려 저하되므로, 스레드 개수가 많아도 캐시 메모리 용량이 적으면 대용량 MLP에 불리하다.

2.7. 캐시 메모리의 최적화 기법

실제 회로 상에 캐시 메모리를 구현할 때는 회로의 면적, 전력 소모 및 타이밍 등의 요소를 고려해야 한다. 또한 현대의 슈퍼스칼라 프로세서에 탑재된 L1 캐시의 경우 한 사이클에 2-3개 이상의 읽기/쓰기를 동시에 처리할 수 있으면서도 캐시의 레이턴시가 1 ns 내외로 낮아야 하고, 기본적으로 대부분의 프로그램은 가상 메모리 주소를 사용하는 점 또한 고려하여야 한다.
  • way prediction
  • cache pipelining
  • multi banked cache
  • line fill buffer & critical word first
  • non blocking

2.8. 캐시 메모리의 종류

2.9. 역사

2.9.1. CPU 캐시 메모리

초창기 캐시 메모리는 1969년에 출시된 IBM의 System/360 Model 85부터 존재했다. 지금의 메인 메모리처럼 카드 및 스틱 형태의 모듈이나 메인보드에 붙어서 CPU와 메인 메모리 사이에 독립적인 칩으로 존재했으나, CPU 집적도가 높아지면서 모토로라 68000 시리즈 기준 1984년에 출시된 68020부터, x86 기준으로 1989년에 출시된 인텔 80486부터 CPU 안에 캐시 메모리가 포함되게 되었다. 캐시 메모리가 내장된 CPU가 등장한 이후에도 CPU 외부에 별도 장착되는 캐시 메모리를 L2 캐시 메모리로 취급했었는데 L2 캐시 메모리는 CPU 클럭 속도와는 별개로 작동했기 때문에, 캐시 메모리의 클럭 속도가 시스템 전반적인 속도에 영향을 주었다.[8] 펜티엄 이후 CPU에서 펜티엄용 메인보드는 CPU 근처에 용량이 정해진 온보드 캐시 메모리뿐만 아니라 별도의 캐시 메모리 슬롯까지 있어서 필요한 경우에 L2 캐시 메모리를 증설할 수도 있었는데 이것이 스틱형 캐시 모듈의 마지막 세대이기도 했다.

그 이후에는 L2 캐시 메모리도 CPU 칩 패키징 내에 넣으려는 시도가 있었고, x86 아키텍처 중 인텔에서는 1995년 11월 출시된 펜티엄 프로에서, AMD에서는 1999년 출시된 K6-III에서 최초로 실현되었다. L2 캐시 메모리가 CPU 내에 통합되기 시작한 시기에는 캐시 메모리가 실장된 형태가 on-die, on-package( MCM)로 구분되어 있었다. on-die 캐시는 하나의 다이 안에 CPU 코어와 L2 캐시 메모리가 함께 포함되어 있는 것이고, on-package 및 그와 유사한 용어는 CPU 코어와 L2 캐시 메모리 다이는 서로 나뉘어 있지만 하나의 패키징된 칩 안에서 서로 연결된 형태를 가리킨다. L2 캐시 메모리까지 CPU에 내장된 덕분에 메인보드에 실장되어 있던 캐시 메모리는 하위 레벨로 밀려나 L3 캐시 메모리로 명명되었다. L2 캐시 메모리까지 내장된 K6-III가 장착된 메인보드의 경우 온보드된 L3 캐시 메모리를 tri-level cache라고 불렀다.

인텔은 펜티엄 프로 시리즈에서 하나의 패키지 안에 CPU 코어와 L2 캐시 메모리 다이를 모두 올리는 형태를 사용했다. 그러나 생산 단가 문제 때문에 일반 사용자를 대상으로 한 펜티엄 2와 초기 펜티엄 3 카트마이 및 셀러론 모델에서는 CPU 코어와 L2 캐시 메모리를 별도 칩으로 분리했고, CPU 형태도 소켓에서 슬롯으로 바꾸었다. 슬롯 1이 사용되던 시기의 인텔 CPU에서는 CPU 코어와 별개로 외부 제조사에서 만든 캐시 메모리용 SRAM이 붙어 있었고, 셀러론은 캐시 메모리가 붙어 있지 않거나 용량이 더 작았다. AMD도 K6-III에서 on-die L2 캐시 메모리를 도입했으나, 인텔과 같은 이유로 인해서 초기형 애슬론은 슬롯 형태로 전환했다. 이 당시 쓰인 외부 캐시는 기술력 및 단가의 한계 때문에 제조사와 모델에 따라 다르지만 CPU 클럭 스피드의 30~50%의 속도로 동작했다. 그러나 기술이 발전하여 on-die 캐시 메모리를 만들기 쉬워졌고, 외부 캐시 메모리의 클럭 레이트를 끌어 올리는 데에는 한계가 있기 때문에 인텔은 멘도시노 셀러론[9], 펜티엄 3 코퍼마인, AMD는 애슬론 선더버드부터 on-die L2 캐시 메모리로 복귀했다. 슬롯이 다시 소켓으로 돌아간 것은 보너스. 캐시 메모리의 속도 역시 CPU와 동기화돼서 성능 또한 향상되었다.

인텔은 초창기의 인텔 셀러론 시리즈인 코빙턴에서 L2 캐시 메모리를 없앴다가 엄청난 성능 저하를 보였다. 물론 L2 캐시 메모리가 원래 없었던 펜티엄 MMX와 동급 내지는 약간 더 나은 성능이긴 했으나, L2 캐시 메모리 있는 CPU와의 성능 격차가 너무 컸다. 이후 인텔은 아무리 저가형 모델이라고 하더라도 L2 캐시 메모리는 용량이 작더라도 항상 달고 나오기 시작했다. 펜티엄 3~4의 전환기에는 일부 투알라틴 코어의 셀러론은 L2 캐시가 256KB나 되어 코퍼마인 펜티엄 3보다 높은 성능인 제품도 있었다.

현세대에는 최소 L2, 보통 L3까지 존재한다. L3 캐시 메모리가 내장된 CPU는 인텔은 2002년 1세대 제온 MP 시리즈인 포스터 MP부터 도입되었다.

파일:external/www.hardwareoverclock.com/P4-EE-10%20Kopie.jpg
데스크탑 제품군에서는 2003년에 출시된 갤러틴 제온을 기반으로 급조된 펜티엄 4 Extreme Edition[10], 2008년 이후의 인텔 코어 i 시리즈가 있으며 AMD는 2007년 AMD 페넘 시리즈에서 L3 캐시 메모리를 도입한 후, AMD 페넘 II 시리즈, AMD FX 시리즈, AMD RYZEN 시리즈 등이 있다. 당연히 단계가 내려갈수록 용량은 증가하며, 반대로 속도는 상대적으로 떨어지게 된다. 물론 코어2 쿼드같이 L2 캐시가 12MB나 달린 깡패가 있긴 하다[11]

Intel Pentium 4 프로세서에 도입된 Trace 캐시와 현대 x86 프로세서의 경우 μop(micro-operation) 캐시라는 개념이 도입되었는데 이는 x86이 CISC라는 점에서 생긴 특징적인 캐시이다.
CISC라는 특성상 한개의 명령어는 프로세서 입장에서 보면 한 개를 초과하는 동작을 하는 추상적인 명령어가 존재하며 가변적인 길이라는 특징을 가지고 있으므로 이 명령어를 실행시키기 위해서는 파이프라인이 복잡해진다. 이 때문에 P6 아키텍처의 경우 파이프라인을 경량화하고 효율성을 증가시키기 위해 RISC의 설계 철학을 도입하여 CISC 명령을 RISC와 같이 개별 명령어로 쪼갠 μop(micro-operation)개념을 도입했다. 하지만 CISC 명령어를 μop으로 변환하는 과정을 매 인스트럭션 사이클마다 반복해야 하므로 디코더의 부하가 증가하는 것에 비해 μop 캐시를 사용하면 CISC에서 μop로 디코딩된 RISC 같은 명령어가 들어 있어 디코딩 단계를 우회하는 데 사용된다. 단, 일반적으로 마이크로옵의 크기가 명령어의 평균적인 크기보다 크기 때문에 면적당 성능에 집중한 아톰 계열 마이크로아키텍처에는 사용되지 않는다.

2015년 2분기 인텔의 코어 5세대 브로드웰 아키텍처 i7-5775c가 출시되었다. eDRAM 128MB의 초고용량[12] L4 캐시 메모리를 탑재했다. 주목적은 CPU 내부의 내장 그래픽 캐시용이지만 내장 그래픽을 사용하지 않으면 CPU의 L4 캐시 메모리로 전환해 사용 가능하다. 당시 기준으로 개인용 CPU에 128MB 용량이라는 큰 캐시 메모리를 사용했으나 5세대 브로드웰 자체가 바로 얼마 뒤 나온 6세대 스카이레이크에 밀려서 크게 주목받지 못했다. 그러나 성능 향상 하나는 확실해서 캐시 메모리 의존도가 높은 게임 분야나 서버 분야[13]는 7세대 카비레이크와 맞먹거나 소폭 우위였을 정도로 성능이 좋았다.

2022년 4월 3D V-Cache 기술을 사용한 Ryzen 7 5800X3D가 출시되었다. 100MB에 준하는 대용량 캐시를 수직 적층이라는 기술로 접목시켜 실현시킨 제품이다. 용량이 큰 만큼 캐시 적중률이 크게 오르고, 수직으로 CPU 코어 위에 가까이 얹어놓았기에 기존 대용량 캐시의 단점인 레이턴시도 크게 늘어지지 않는다.[14] 이에 따라 게임(맵 연산 등)에서 월등한 성능을 보여주며 게임 전용 CPU라는 타이틀을 획득하게 된다. 안타깝게도 게임/서버 외의 다른 작업[15]은 고용량의 캐시 메모리가 필요하지 않기에(이 용량까지 활용할 알고리즘이 없기에) 성능 향상은 미진한 편이긴 하며 3D V 캐시 제품군은 오히려 발열을 더 신경 써야 되기에[16] 코어 i나 Non-3D V-Cache 라이젠이 좋다.

이처럼 반복 작업이 중요한 게임과 서버 분야에서 캐시 메모리가 차지하는 비중이 크기 때문에 개인용 CPU와 고급형 서버 CPU에서 대용량 캐시 메모리를 적용한 제품이 늘어나고 있다. 사실 라이젠 5800X3D 역시 서버용 에픽 프로세서를 만들던 중 부산물이었다고 AMD R&D 센터 견학 중 인터뷰를 통해 밝혔다. #

이처럼 인텔과 AMD의 주도 아래 캐시 메모리의 중요성이 부각되면서 CPU 캐시 메모리 용량이 증가 추세에 있다. 또한 ARM Cortex-X 시리즈 등 고성능 ARM 프로세서에서도 가격 조정을 위해 원래 설계상에서 있던 캐시 메모리를 AP 제조사들이 커스텀하면서 반토막 냈다가 성능에 크게 영향을 받기도 하여 이런 행위를 자제하게 되는 등 다른 CPU 아키텍처에서도 캐시 메모리의 중요성이 커졌다.

2.9.2. GPU 캐시 메모리

그래픽 카드의 GPU 캐시 메모리는 1999년에 등장한 GPU 개념이 잡히기 이전 시절의 프로세서에도 존재했지만, 구체적인 정보가 알려져 있지 않았다. 기껏해야 비디오 게임 콘솔의 GPU가 캐시 메모리처럼 쓸 수 있는 eDRAM 용량 정도였다. GPU 개념이 등장한 이후에도 한동안 찾아내기 어려운 정보였다가 2006년 NVIDIA의 지포스 8 시리즈, 2007년 AMD의 라데온 HD 2000 시리즈부터 용량 정보가 알려지기 시작했다.

CPU처럼 계층 구조가 정립되어 있는데, GPU 전체 레벨에서의 캐시 메모리를 L2 캐시 메모리 혹은 전역 공유 캐시 메모리라고 부르고, NVIDIA의 SM(스트림 멀티프로세서)나 AMD의 SIMD 코어 레벨에서의 캐시 메모리를 L1 캐시 메모리, 로컬 공유 캐시 메모리라고 부르는 편이다. 단, L1 캐시와 로컬 공유 캐시는 서로 별개로 존재하는 영역이기 때문에 어떤 기능을 수행하냐에 따라 거쳐가는 캐시 메모리가 다를 수 있으며, 이 레벨에는 명령어 캐시 메모리, 상수 캐시 메모리도 따로 존재하므로 계층 구조가 은근히 복잡하다. GPU에서의 L1 캐시 메모리는 읽기만 가능한 L1 텍스처 캐시 메모리에 해당한다. L2 캐시 메모리도 과거에는 읽기만 가능한 L2 텍스처 캐시 메모리였으나, 읽기와 쓰기 모두 가능한 L2 공유 캐시 메모리로 발전되었다. 따로따로 존재했던 L1 텍스처 캐시 메모리와 로컬 공유 캐시 메모리도 하나의 L1 캐시 메모리라는 영역의 일부로서 할당되는 방식으로 변경되었다.

2014년 NVIDIA의 맥스웰 아키텍처부터 SM 내에서도 4개의 파티션으로 세분화되면서 파티션마다 명령어 버퍼가 추가되었는데, 2017년 볼타 아키텍처부터는 아예 L0 캐시 메모리로 정립되었다. AMD도 마찬가지로 2019년 RDNA 아키텍처가 처음 도입된 라데온 RX 5000 시리즈부터 계층이 분화되어 기존의 L1 캐시 메모리가 L0로 격상되고 L1와 L2 사이에 캐시 메모리 계층이 추가되어 이를 L1 캐시 메모리로 명명됨에 따라 3계층 구조로 정립되었다.

인텔 내장 그래픽도 기능별 캐시 메모리가 존재했으나 계층 구조가 뚜렷하지 않았고, 2012년 아이비브릿지 세대에 들어서야 L3 캐시 메모리가 등장하면서 모양새를 갖추기 시작했다. 그런데 CPU의 L3 캐시 메모리와 혼동되는 문제 때문인지 CPU의 L3 캐시 메모리를 LLC(라스트 레벨 캐시) 메모리로 취급해 버린 데다, 2013년 하스웰 세대부터 Iris Pro Graphics가 내장된 CPU 한정으로 추가된 eDRAM이 L4 캐시 메모리라고도 부르게 되면서 캐시 메모리 레벨 명칭이 애매해졌다. 참고로 eDRAM은 속도가 빠르고 대역폭도 넓다 보니 eDRAM이 없는 기존의 HD Graphics 계열과는 차원이 다른 성능을 보여줬다. 가격도 차원이 달랐다. 그나마도 성능이 레이븐 릿지에 못 미친 것은 덤

2.10. 캐시 메모리와 버퍼 메모리

하드 디스크 사이의 속도 향상을 위해서 적게는 수 MB, 많게는 수백 MB 정도의 메모리를 달아서 좀 더 빠른 입력에서도 대응하여 출력이 가능하도록 지원한다. 이를 버퍼 메모리라고 부르며, 하드 디스크에 있는 버퍼 메모리라고 해서 디스크 버퍼라고도 부르는데 얼핏 보면 캐시 메모리와 비슷해 보이지만, 목적이 전혀 다른 용도의 메모리이다. 캐시 메모리는 성능 향상을 목적으로 나온 메모리인 반면, 버퍼 메모리는 성능에 상관없이 사용자가 원하는 데이터 입출력을 완전하게 구현하기 위한 목적으로 나온 메모리라는 것. 이에 대한 자세한 내용은 버퍼 문서 참조.

SSD에도 동일한 개념의 버퍼 & 캐시 겸용 메모리가 달려 있는데 시스템 메모리에 흔히 보는 DDR 계열의 S DRAM이 사용된다. SSHD의 경우 하드 디스크의 버퍼를 아예 저용량의 SSD랑 섞어버린 것.

메인 메모리의 일부를 떼어서 HDD/SSD의 데이터를 캐싱하는 것도 가능하며 이를 페이지 캐시라고 부른다. DOS 시절 1MB 메모리가 달린 286 이상의 컴퓨터에는 640kiB를 넘어가는 상위 메모리 영역의 일부를 디스크 캐시로 사용할 수 있도록 해 주는 유틸리티가 여러 종류 있었다. 이후 Windows 95로 넘어오면서 운영 체제에서 자체적으로 디스크 캐시를 제공하게 되었다. Linux 등의 유닉스 계열 운영 체제도 디스크 캐시를 기본 기능으로 보유하고 있다. '디스크 캐시'라고 부르기도 하지만, 보조 저장 장치에 탑재된 '디스크 버퍼'와 혼동될 뿐만 아니라 메인 메모리 용량 부족으로 보조 저장 장치의 일부 용량을 메인 메모리 용도로 할당해서 사용하는 디스크 스왑와는 전혀 다른 개념이므로 주의할 것.

3. 관련 자료

4. 관련 문서



[1] 인버터 2개에 워드 라인 및 비트 라인을 연결한 기본적인 구조의 SRAM [2] 6T SRAM에 읽기 전용 워드 라인 및 비트 라인을 추가한 구조 [3] 단 엘더 이후 인텔 E코어는 코어 넷이 L2를 공유하는 구조를 가지고 있다. [4] x86의 cldemote, clflushopt, prefetchwt1 [5] PC Perspective 웹사이트의 ' E3: Intel Confident It Will Retain Gaming Performance Leadership Over Ryzen 3000' 게시 글에서 확인할 수 있다. [6] 블록 오프셋 필드(Offset Field)라고도 부른다. [7] 주로 네트워크 분야에서 라우팅 테이블이나 MAC 테이블의 작업 성능을 향상 시킬 목적으로 사용되는 편이다. [8] 펜티엄 2 CPU [9] 더블 오버클럭 유행을 주도함. [10] 원래 제온 시리즈에서만 볼 수 있었던 캐시 메모리였기 때문에 후속작인 프레스캇 기반의 펜티엄 4 익스트림 에디션은 L3 캐시 메모리가 없다. [11] 참고로 2600K조차 L3 캐시가 8MB이며 13100F의 경우 16MB다. 12900K조차도 L2 캐시가 14MB다. [12] 2014년 기준 L3 캐시는 8MB(i7), 6MB(i5), 4MB(i3)가 일반적이었고, 2022년 기준으로도 30MB 이상 L3 캐시는 인텔 기준 i7, i9에만 탑재될 정도로 대용량으로 취급받는다. [13] 서버와 같이 했던 작업 또 반복적으로 하는 일이라면 캐시가 늘어난 만큼 성능이 오르기는 한다. [14] 캐시 용량이 커질수록 넓은 면적을 차지하게 되고, 면적이 넓어질수록 코어와 캐시와의 거리는 멀어져 레이턴시가 증가하게 된다. 무턱대고 고용량의 캐시를 넣는다 해서 성능 향상을 기대할 수 없는 이유이다.(물론 캐시 메모리가 비싸기도 하다는 어른의 사정이 있지만(...)) [15] 새로운 데이터를 디스크에서 읽어 오고, 연산이 끝나 넘긴 후에는 이를 반복해서 활용하지 않는 작업들. [16] 그러다보니 배수락이 걸려 있어 오버클럭이 불가능하며 전압 조정도 최대 1.35V로 3D V-Cache가 적용되지 않은 CPU보다 낮은 편이다.

분류