# CPU 캐시

동적 CPU 메모리 캐시 그림
**CPU 캐시**(CPU cache)는 중앙 처리 장치(CPU)에서 메인 메모리에서 데이터에 접근하는 평균 비용(시간 또는 에너지)을 줄이기 위해 사용하는 하드웨어 캐시이다. 캐시는 프로세서 코어에 더 가깝게 위치한 더 작고 빠른 메모리로, 자주 사용되는 메인 메모리 위치의 데이터 복사본을 저장하여 수십에서 수백 배 느릴 수 있는 메인 메모리에 항상 접근할 필요가 없도록 한다.

캐시 메모리는 일반적으로 단일 비트를 저장하는 데 여러 트랜지스터를 필요로 하는 SRAM으로 구현된다. 이로 인해 면적 측면에서 비용이 많이 들고, 최신 CPU에서 캐시는 일반적으로 칩 면적에서 가장 큰 부분을 차지한다. 캐시의 크기는 칩의 크기를 줄이고 비용을 절감하려는 일반적인 욕구와 균형을 이루어야 한다. 일부 최신 설계는 전체 캐시 또는 일부를 물리적으로 더 작은 eDRAM을 사용하여 구현하는데, 이는 SRAM보다 느리지만 주어진 칩 면적에 더 많은 캐시를 허용한다.

대부분의 CPU는 여러 캐시 수준(L1, L2, 종종 L3, 드물게 L4)의 계층 구조를 가지며, L1 수준에는 별도의 명령어 전용(I-캐시) 및 데이터 전용(D-캐시) 캐시가 있다. 다른 수준들은 칩의 다른 영역에 구현된다. L1은 CPU 코어에 가능한 한 가깝게 위치하여 신호 경로가 짧아 최고 속도를 제공하지만 신중한 설계가 필요하다. L2 캐시는 CPU와 물리적으로 분리되어 더 느리게 작동하지만 칩 설계자의 요구가 적고 CPU 설계에 영향을 미치지 않으면서 훨씬 더 크게 만들 수 있다. L3 캐시는 일반적으로 여러 CPU 코어 간에 공유된다.

다른 유형의 캐시도 존재하며(위에서 언급한 가장 중요한 캐시의 "캐시 크기"에는 포함되지 않음), 예를 들어 대부분의 CPU에 있는 MMU의 일부인 TLB가 있다. 입출력 섹션에는 비슷한 목적을 수행하는 데이터 버퍼도 종종 포함된다.

## 개요

메인 메모리의 데이터에 접근하기 위해서는 여러 단계의 과정이 사용되며, 각 단계는 지연을 발생시킨다. 예를 들어, 간단한 컴퓨터 시스템에서 메모리에서 값을 읽으려면 CPU는 먼저 주소 버스에 표현하여 접근할 주소를 선택하고, 값이 안정화될 때까지 정해진 시간 동안 기다린다. 그 값을 가진 메모리 장치(일반적으로 DRAM으로 구현됨)는 CPU가 직접 읽기에는 충분히 강력하지 않은 매우 낮은 에너지 형태로 그 값을 유지한다. 대신, 그 값은 저장소에서 데이터 버스에 연결된 작은 버퍼로 복사되어야 한다. 그런 다음 CPU는 데이터 버스에서 값을 읽기 전에 이 값이 안정화될 때까지 특정 시간 동안 기다린다.

메모리를 CPU에 물리적으로 더 가깝게 배치함으로써 버스가 안정화되는 데 필요한 시간이 줄어들고, DRAM을 SRAM으로 교체함으로써 읽기를 위해 증폭이 필요 없는 형태로 값을 유지하여 메모리 자체 내의 지연이 제거된다. 이로 인해 캐시는 응답 및 읽기/쓰기 모두에서 훨씬 빨라진다. 그러나 SRAM은 유형에 따라 단일 비트를 유지하는 데 4개에서 6개의 트랜지스터를 필요로 하는 반면, DRAM은 일반적으로 비트당 하나의 트랜지스터와 하나의 커패시터를 사용하여 주어진 칩 면적에 훨씬 더 많은 데이터를 저장할 수 있다.

일부 메모리를 더 빠른 형식으로 구현하면 성능이 크게 향상될 수 있다. 메모리 위치에서 읽거나 쓰려고 할 때 프로세서는 해당 위치의 데이터가 이미 캐시에 있는지 확인한다. 있다면 프로세서는 훨씬 느린 메인 메모리 대신 캐시에서 읽거나 쓸 것이다.

많은 최신 데스크톱, 서버 및 산업용 CPU는 최소 세 가지 독립적인 캐시 수준(L1, L2, L3)과 다양한 유형의 캐시를 가지고 있다.

TLB (Translation lookaside buffer)실행 가능한 명령어와 데이터 모두에 대한 가상-물리 주소 변환 속도를 높이는 데 사용된다. 단일 TLB는 명령어와 데이터 모두에 대한 접근을 위해 제공될 수 있으며, 또는 별도의 명령어 TLB (ITLB)와 데이터 TLB (DTLB)가 제공될 수 있다. 그러나 TLB 캐시는 MMU의 일부이며 CPU 캐시와 직접적인 관련이 없다.
**명령어 캐시**
마이크로 오퍼레이션-캐시
분기 대상 버퍼
명령어 캐시 (I-캐시)실행 가능한 명령어 가져오기 속도 향상에 사용됨
**데이터 캐시**
데이터 캐시 (D-캐시)데이터 가져오기 및 저장 속도 향상에 사용됨; 데이터 캐시는 일반적으로 더 많은 캐시 수준(L1, L2 등; 아래 멀티 레벨 캐시 참조)의 계층 구조로 구성된다.
## 역사

넥스트큐브 컴퓨터 (1990)의 메인보드. 이미지 아래쪽 가장자리 중앙에서 왼쪽으로 모토로라 68040 CPU가 25 MHz로 작동하며, 칩 위에 4KiB씩 분리된 레벨 1 캐시 두 개(하나는 명령어용, 다른 하나는 데이터용)가 있다. 이 보드에는 외부 L2 캐시가 없다.
CPU 캐시의 초기 사례로는 1960년대의 아틀라스 2와 IBM 시스템/360 모델 85가 있다. 캐시를 사용한 최초의 CPU는 단일 수준의 캐시만 가졌다. 이후의 레벨 1 캐시와는 달리 L1d(데이터용)와 L1i(명령어용)로 분할되지 않았다. 분할 L1 캐시는 1976년 IBM 801 CPU부터 시작되었으며, 1980년대 후반에 주류가 되었고, 1997년에 ARMv5TE로 임베디드 CPU 시장에 진입했다. 2015년에는 1달러 미만의 SoC조차 L1 캐시를 분할했다. 또한 L2 캐시와 더 큰 프로세서의 경우 L3 캐시도 있다. L2 캐시는 일반적으로 분할되지 않으며, 이미 분할된 L1 캐시의 공통 저장소 역할을 한다. 멀티 코어 프로세서의 각 코어는 전용 L1 캐시를 가지며 일반적으로 코어 간에 공유되지 않는다. L2 캐시와 하위 수준 캐시는 코어 간에 공유될 수 있다. L4 캐시는 현재 흔하지 않으며, 일반적으로 SRAM이 아닌 별도의 다이 또는 칩에 있는 DRAM이다. 예외는 모든 캐시 수준(L1까지)에 eDRAM이 사용되는 경우이다. 역사적으로 L1도 별도의 다이에 있었지만, 더 큰 다이 크기로 인해 마지막 수준을 제외하고는 다른 캐시 수준과 함께 통합될 수 있었다. 각 추가 캐시 수준은 하위 수준보다 작고 빠른 경향이 있다.

캐시(RAM의 역사와 마찬가지로)는 일반적으로 2, 4, 8, 16 등 KiB의 멱수로 크기가 정해져 왔다. MiB 크기(즉, 더 큰 비-L1 캐시)의 경우 초기에는 크기를 두 배로 늘리는 패러다임에 얽매이지 않고 더 큰 캐시를 허용하기 위해 패턴이 무너졌는데, 예를 들어 2008년 4월에 인텔 코어 2 듀오는 3 MiB L2 캐시를 가졌다. L1 캐시의 경우 훨씬 나중에 발생했는데, L1 캐시의 크기는 일반적으로 여전히 작은 수의 KiB이다. 2012년 IBM zEC12는 예외적으로 당시로서는 이례적으로 큰 96 KiB L1 데이터 캐시를 얻었고, 예를 들어 IBM z13은 96 KiB L1 명령어 캐시(및 128 KiB L1 데이터 캐시)를 가졌으며, 2018년 아이스레이크 기반 프로세서는 48 KiB L1 데이터 캐시와 48 KiB L1 명령어 캐시를 가졌다. 2020년에는 일부 인텔 아톰 CPU(최대 24코어)가 4.5 MiB 및 15 MiB 캐시 크기(여러 개)를 가졌다.

## 작동

### 캐시 엔트리

데이터는 캐시 라인 또는 캐시 블록이라고 불리는 고정 크기 블록으로 메모리와 캐시 간에 전송된다. 캐시 라인이 메모리에서 캐시로 복사될 때 캐시 엔트리가 생성된다. 캐시 엔트리에는 복사된 데이터와 요청된 메모리 위치(태그라고 불림)가 포함된다.

프로세서가 메모리 위치를 읽거나 써야 할 때, 먼저 캐시에서 해당 엔트리를 확인한다. 캐시는 해당 주소를 포함할 수 있는 캐시 라인에서 요청된 메모리 위치의 내용을 확인한다. 프로세서가 캐시에서 메모리 위치를 찾으면 **캐시 적중**이 발생한 것이다. 그러나 프로세서가 캐시에서 메모리 위치를 찾지 못하면 **캐시 미스**가 발생한 것이다. 캐시 적중의 경우 프로세서는 캐시 라인의 데이터를 즉시 읽거나 쓴다. 캐시 미스의 경우 캐시는 새 엔트리를 할당하고 메인 메모리에서 데이터를 복사한 다음 캐시 내용에서 요청을 처리한다.

### 정책

#### 교체 정책

캐시 미스 시 새 엔트리를 위한 공간을 확보하기 위해 캐시는 기존 엔트리 중 하나를 제거해야 할 수 있다. 제거할 엔트리를 선택하는 데 사용하는 휴리스틱은 교체 정책이라고 불린다. 모든 교체 정책의 근본적인 문제는 미래에 가장 적게 사용될 가능성이 있는 기존 캐시 엔트리를 예측해야 한다는 것이다. 미래를 예측하는 것은 어렵기 때문에 사용 가능한 다양한 교체 정책 중에서 완벽한 선택 방법은 없다. 인기 있는 교체 정책 중 하나인 최근 사용 최소 (LRU)는 가장 최근에 접근하지 않은 엔트리를 교체한다.

일부 메모리 범위를 캐시 불가능으로 표시하면 성능을 향상시킬 수 있는데, 이는 거의 다시 접근되지 않는 메모리 영역의 캐싱을 피할 수 있기 때문이다. 이렇게 하면 재사용 없이 캐시에 무언가를 로드하는 오버헤드를 피할 수 있다. 캐시 엔트리는 컨텍스트에 따라 비활성화되거나 잠길 수도 있다.

#### 쓰기 정책

캐시에 데이터가 기록되면 어느 시점에는 메인 메모리에도 기록되어야 한다. 이 기록의 시기는 쓰기 정책이라고 알려져 있다. 쓰기 관통 캐시에서는 캐시에 대한 모든 쓰기가 메인 메모리에 대한 쓰기를 유발한다. 반대로, 쓰기 지연 또는 복사-백 캐시에서는 쓰기가 즉시 메인 메모리에 반영되지 않으며, 덮어쓴 위치는 더티로 표시되어 캐시에서 제거될 때만 메인 메모리에 다시 기록된다. 이 때문에 쓰기 지연 캐시에서 읽기 미스가 발생하면 두 번의 메모리 접근이 필요할 수 있다. 즉, 먼저 더티 위치를 메인 메모리에 기록한 다음, 새 위치를 메모리에서 읽는 것이다. 또한, 쓰기 지연 캐시에 아직 매핑되지 않은 메인 메모리 위치에 대한 쓰기는 이미 더티인 위치를 제거하여 새 메모리 위치를 위한 캐시 공간을 확보할 수 있다.

중간 정책도 있다. 캐시는 쓰기 관통 방식일 수 있지만, 쓰기는 일시적으로 저장 데이터 큐에 보류될 수 있는데, 이는 일반적으로 여러 저장이 함께 처리될 수 있도록 하기 위함이다(이는 버스 턴어라운드를 줄이고 버스 활용도를 높일 수 있다).

메인 메모리에서 캐시된 데이터는 다른 엔티티(예: DMA를 사용하는 주변 장치 또는 멀티 코어 프로세서의 다른 코어)에 의해 변경될 수 있으며, 이 경우 캐시의 복사본이 오래되거나 구식이 될 수 있다. 또는 다중 처리 시스템의 CPU가 캐시의 데이터를 업데이트할 때, 다른 CPU와 관련된 캐시의 데이터 복사본이 구식이 된다. 캐시 관리자 간에 데이터를 일관성 있게 유지하는 통신 프로토콜을 캐시 일관성 프로토콜이라고 한다.

### 캐시 성능

캐시 성능 측정은 메모리 성능과 프로세서 성능 간의 속도 차이가 기하급수적으로 증가하는 최근 들어 중요해졌다. 캐시는 이러한 속도 차이를 줄이기 위해 도입되었다. 따라서 캐시가 프로세서와 메모리 속도 간의 격차를 얼마나 잘 메울 수 있는지 아는 것은 특히 고성능 시스템에서 중요하다. 캐시 적중률과 캐시 미스율은 이 성능을 결정하는 데 중요한 역할을 한다. 캐시 성능을 향상시키기 위해서는 미스율을 줄이는 것이 다른 단계들 중에서 필수적인 단계가 된다. 캐시에 대한 접근 시간을 줄이는 것도 성능을 향상시키고 최적화에 도움이 된다.

#### CPU 스톨

메모리에서 캐시 라인 하나를 가져오는 데 걸리는 시간(지연 시간, 캐시 미스로 인한 읽기 지연)은 CPU가 캐시 라인을 기다리는 동안 할 일이 없어지기 때문에 중요하다. CPU가 이 상태에 도달하면 스톨(stall)이라고 불린다. CPU가 메인 메모리에 비해 더 빨라짐에 따라 캐시 미스로 인한 스톨은 더 많은 잠재적 연산을 방해한다. 최신 CPU는 메인 메모리에서 단일 캐시 라인을 가져오는 데 걸리는 시간에 수백 개의 명령어를 실행할 수 있다.

이 시간 동안 CPU를 바쁘게 유지하기 위해 다양한 기술이 사용되었는데, 여기에는 비순차적 명령어 처리가 포함되어 CPU가 캐시 미스 데이터를 기다리는 명령어 이후에 독립적인 명령어를 실행하려고 시도한다. 많은 프로세서에서 사용되는 또 다른 기술은 SMT(simultaneous multithreading)로, 첫 번째 스레드가 필요한 CPU 리소스가 사용 가능해질 때까지 기다리는 동안 대체 스레드가 CPU 코어를 사용할 수 있도록 한다.

## 연관성

메모리 위치가 특정 캐시 위치에 캐시될 수 있는 다양한 방법을 보여주는 그림
배치 정책은 특정 주 기억 장치 엔트리의 복사본이 캐시의 어디로 갈지 결정한다. 배치 정책이 캐시의 어떤 엔트리든 자유롭게 선택하여 복사본을 저장할 수 있다면, 이 캐시는 완전 연관 캐시라고 불린다. 다른 극단으로는, 주 기억 장치의 각 엔트리가 캐시의 한 곳으로만 갈 수 있다면, 이 캐시는 직접 매핑 캐시라고 불린다. 많은 캐시는 주 기억 장치의 각 엔트리가 캐시의 N개의 장소 중 하나로 갈 수 있도록 하는 절충안을 구현하며, N-방향 집합 연관 캐시로 설명된다. 예를 들어, AMD 애슬론의 레벨 1 데이터 캐시는 2-방향 집합 연관 방식인데, 이는 주 기억 장치의 특정 위치가 레벨 1 데이터 캐시의 두 위치 중 하나에 캐시될 수 있다는 의미이다.

연관성의 올바른 값을 선택하는 것은 트레이드오프를 수반한다. 배치 정책이 메모리 위치를 매핑할 수 있는 10개의 장소가 있다면, 해당 위치가 캐시에 있는지 확인하려면 10개의 캐시 엔트리를 검색해야 한다. 더 많은 장소를 확인하는 것은 더 많은 전력과 칩 면적을 소비하며, 잠재적으로 더 많은 시간이 걸린다. 반면에, 더 많은 연관성을 가진 캐시는 미스(미스율)가 적어(충돌 미스 참조) CPU가 느린 주 기억 장치에서 읽는 데 시간을 덜 낭비한다. 일반적인 지침은 연관성을 직접 매핑에서 2-방향으로, 또는 2-방향에서 4-방향으로 두 배로 늘리는 것이 캐시 크기를 두 배로 늘리는 것과 적중률을 높이는 데 거의 동일한 효과를 가진다는 것이다. 그러나 연관성을 4 이상으로 늘리는 것은 적중률을 그만큼 많이 향상시키지 않으며, 일반적으로 다른 이유(예: 가상 에일리어싱)로 수행된다. 일부 CPU는 저전력 상태에서 캐시의 연관성을 동적으로 줄일 수 있는데, 이는 전력 절약 조치로 작용한다.

최악이지만 단순한 것부터 최고지만 복잡한 순서:

* 직접 매핑 캐시: 최적의 최적 사례 시간을 제공하지만 최악의 경우에는 예측 불가능하다.
* 2-방향 집합 연관 캐시
* 2-방향 스큐 연관 캐시
* 4-방향 집합 연관 캐시
* 8-방향 집합 연관 캐시: 후기 구현에 일반적인 선택
* 12-방향 집합 연관 캐시: 8-방향과 유사
* 완전 연관 캐시: 최적의 미스율을 제공하지만 적은 수의 엔트리에서만 실용적이다.

### 직접 매핑 캐시

이 캐시 구성에서 주 기억 장치의 각 위치는 캐시의 하나의 엔트리에만 들어갈 수 있다. 따라서 직접 매핑 캐시는 "1-방향 집합 연관" 캐시라고도 불린다. 이 캐시는 제거할 캐시 엔트리의 내용에 대한 선택권이 없으므로 배치 정책이 없다. 이는 두 위치가 동일한 엔트리에 매핑되는 경우 서로를 계속해서 쫓아낼 수 있음을 의미한다. 직접 매핑 캐시는 더 간단하지만, 비슷한 성능을 제공하려면 연관 캐시보다 훨씬 더 커야 하며 예측 가능성이 떨어진다. 캐시의 블록 번호를 WIKINIUM\_MATH\_PH\_0 , 메모리의 블록 번호를 WIKINIUM\_MATH\_PH\_1 , 캐시의 블록 수를 WIKINIUM\_MATH\_PH\_2 이라고 하면, 매핑은 WIKINIUM\_MATH\_PH\_3 공식을 사용하여 수행된다.

### 2-방향 집합 연관 캐시

주 기억 장치의 각 위치가 캐시의 두 위치 중 하나에 캐시될 수 있다면, 한 가지 논리적인 질문은: 둘 중 어느 것인가? 위 오른쪽 그림에 나타난 가장 간단하고 일반적으로 사용되는 방식은 메모리 위치 인덱스의 최하위 비트를 캐시 메모리의 인덱스로 사용하고, 각 인덱스에 대해 두 개의 엔트리를 갖는 것이다. 이 방식의 한 가지 이점은 캐시에 저장된 태그가 캐시 메모리의 인덱스에 의해 암시되는 주 기억 장치 주소의 해당 부분을 포함할 필요가 없다는 것이다. 캐시 태그의 비트 수가 적으므로 트랜지스터 수가 적게 필요하고, 프로세서 회로 기판 또는 마이크로프로세서 칩에서 더 적은 공간을 차지하며, 더 빠르게 읽고 비교할 수 있다. 또한 LRU 알고리즘은 각 쌍에 대해 하나의 비트만 저장하면 되므로 특히 간단하다.

### 투기적 실행

직접 매핑 캐시의 장점 중 하나는 간단하고 빠른 투기적 실행을 허용한다는 것이다. 주소가 계산되면, 메모리의 해당 위치 복사본을 가질 수 있는 캐시 인덱스가 하나만 알려진다. 해당 캐시 엔트리는 읽을 수 있으며, 프로세서는 태그가 실제로 요청된 주소와 일치하는지 확인하기 전에 해당 데이터로 계속 작업할 수 있다.

태그 일치가 완료되기 전에 프로세서가 캐시된 데이터를 사용하는 아이디어는 연관 캐시에도 적용될 수 있다. 힌트라고 불리는 태그의 하위 집합은 요청된 주소에 매핑되는 가능한 캐시 엔트리 중 하나만 선택하는 데 사용될 수 있다. 힌트에 의해 선택된 엔트리는 전체 태그를 확인하는 것과 병렬로 사용될 수 있다. 힌트 기술은 아래에서 설명하는 주소 변환의 맥락에서 사용될 때 가장 잘 작동한다.

### 2-방향 스큐 연관 캐시

스큐 캐시와 같은 다른 방식도 제안되었다. 이 방식에서는 웨이 0에 대한 인덱스가 위에서처럼 직접적이지만, 웨이 1에 대한 인덱스는 해시 함수를 사용하여 형성된다. 좋은 해시 함수는 직접 매핑과 충돌하는 주소가 해시 함수로 매핑될 때는 충돌하지 않는 경향이 있어, 병리학적 접근 패턴으로 인해 예상치 못하게 많은 충돌 미스가 발생하는 프로그램의 가능성을 줄여준다. 단점은 해시 함수 계산으로 인한 추가 지연이다. 또한, 새 라인을 로드하고 오래된 라인을 제거해야 할 때, 각 웨이에서 다른 인덱스의 데이터와 새 라인이 충돌하기 때문에 어떤 기존 라인이 가장 최근에 사용되지 않았는지 결정하기 어려울 수 있다. LRU 추적은 일반적으로 스큐되지 않은 캐시의 경우 세트별로 수행된다. 그럼에도 불구하고 스큐 연관 캐시는 기존의 집합 연관 캐시보다 큰 장점을 가지고 있다.

### 가상 연관 캐시

진정한 집합 연관 캐시는 내용 주소화 기억장치와 같은 것을 사용하여 가능한 모든 웨이를 동시에 테스트한다. 가상 연관 캐시는 가능한 각 웨이를 한 번에 하나씩 테스트한다. 해시-리해시 캐시와 컬럼 연관 캐시는 가상 연관 캐시의 예이다.

테스트된 첫 번째 웨이에서 적중이 발생하는 일반적인 경우, 가상 연관 캐시는 직접 매핑 캐시만큼 빠르지만, 직접 매핑 캐시보다 훨씬 낮은 충돌 미스율을 가지며 완전 연관 캐시의 미스율에 가깝다.

### 다중 열 캐시

직접 매핑 캐시와 비교하여 집합 연관 캐시는 캐시 세트 인덱스에 대한 비트 수가 줄어든다. 이 인덱스는 캐시 세트에 매핑되며, 2-방향 집합 연관 캐시의 경우 2개 블록, 4-방향 집합 연관 캐시의 경우 4개 블록과 같이 여러 웨이 또는 블록이 존재한다. 직접 매핑 캐시와 비교하여 사용되지 않는 캐시 인덱스 비트는 태그 비트의 일부가 된다. 예를 들어, 2-방향 집합 연관 캐시는 태그에 1비트를 추가하고, 4-방향 집합 연관 캐시는 태그에 2비트를 추가한다. 다중 열 캐시의 기본 아이디어는 기존의 집합 연관 캐시처럼 세트 인덱스를 사용하여 캐시 세트에 매핑하고, 추가된 태그 비트를 사용하여 세트 내의 웨이를 인덱싱하는 것이다. 예를 들어, 4-방향 집합 연관 캐시에서 두 비트는 각각 웨이 00, 웨이 01, 웨이 10, 웨이 11을 인덱싱하는 데 사용된다. 이러한 이중 캐시 인덱싱을 "주요 위치 매핑"이라고 하며, 그 지연 시간은 직접 매핑 접근과 동일하다. 다중 열 캐시 설계에 대한 광범위한 실험은 주요 위치에 대한 적중률이 90%에 달한다는 것을 보여준다. 캐시 매핑이 주요 위치의 캐시 블록과 충돌하면, 기존 캐시 블록은 동일한 세트의 다른 캐시 웨이로 이동되는데, 이를 "선택된 위치"라고 한다. 새로 인덱싱된 캐시 블록은 가장 최근에 사용된(MRU) 블록이므로, 시간적 지역성을 고려하여 다중 열 캐시의 주요 위치에 배치된다. 다중 열 캐시는 높은 연관성을 가진 캐시를 위해 설계되었으므로 각 세트의 웨이 수가 많아 세트에서 선택된 위치를 찾기 쉽다. 추가 하드웨어에 의해 인덱싱된 선택된 위치는 캐시 블록의 주요 위치에 대해 유지된다.

다중 열 캐시는 높은 연관성으로 인해 높은 적중률을 유지하며, 주요 위치에서의 높은 적중률로 인해 직접 매핑 캐시와 비슷한 낮은 지연 시간을 갖는다. 다중 열 캐시의 주요 위치 및 선택된 위치 개념은 ARM 코어텍스 R 칩, 인텔의 웨이 예측 캐시 메모리, IBM의 재구성 가능한 다중 웨이 연관 캐시 메모리 및 오라클의 주소 탭 비트를 기반으로 한 동적 캐시 교체 웨이 선택과 같은 여러 캐시 설계에서 사용되었다.

## 캐시 엔트리 구조

캐시 행 엔트리는 일반적으로 다음 구조를 갖는다.

|  |  |  |
| --- | --- | --- |
| 태그 | 데이터 블록 | 플래그 비트 |

데이터 블록(캐시 라인)은 주 기억 장치에서 가져온 실제 데이터를 포함한다. 태그는 주 기억 장치에서 가져온 실제 데이터의 주소(일부)를 포함한다. 플래그 비트는 아래에서 설명한다.

캐시의 "크기"는 캐시가 담을 수 있는 주 기억 장치 데이터의 양이다. 이 크기는 각 데이터 블록에 저장된 바이트 수에 캐시에 저장된 블록 수를 곱하여 계산할 수 있다. (태그, 플래그 및 오류 수정 코드 비트는 크기에 포함되지 않지만, 캐시의 물리적 면적에 영향을 미친다.)

캐시 라인(메모리 블록)과 함께 사용되는 유효 메모리 주소는 태그, 인덱스 및 블록 오프셋으로 분할된다(MSB에서 LSB 순서).

|  |  |  |
| --- | --- | --- |
| 태그 | 인덱스 | 블록 오프셋 |

인덱스는 데이터가 어떤 캐시 세트에 들어갔는지 설명한다. 인덱스 길이는 WIKINIUM\_MATH\_PH\_4 개의 캐시 세트에 대해 WIKINIUM\_MATH\_PH\_5 비트이다.

블록 오프셋은 캐시 행에 저장된 데이터 블록 내에서 원하는 데이터를 지정한다. 일반적으로 유효 주소는 바이트 단위이므로 블록 오프셋 길이는 WIKINIUM\_MATH\_PH\_7 비트이며, 여기서 WIKINIUM\_MATH\_PH\_9 는 데이터 블록당 바이트 수이다.
태그는 주소의 최상위 비트를 포함하며, 현재 세트(인덱스로 검색된 세트)의 모든 행과 비교하여 이 세트가 요청된 주소를 포함하는지 확인한다. 포함하면 캐시 적중이 발생한다. 태그 길이는 비트 단위로 다음과 같다.

`tag_length = address_length - index_length - block_offset_length`
일부 저자는 블록 오프셋을 단순히 "오프셋" 또는 "변위"라고 부른다.

### 예시

오리지널 펜티엄 4 프로세서는 8 KiB 크기의 4-방향 집합 연관 L1 데이터 캐시를 가졌고, 캐시 블록 크기는 64바이트였다. 따라서 8 KiB / 64 = 128개의 캐시 블록이 존재했다. 세트 수는 캐시 블록 수를 연관 방식의 수로 나눈 것과 같으므로 128 / 4 = 32개의 세트가 있었고, 따라서 25 = 32개의 서로 다른 인덱스가 존재했다. 가능한 오프셋은 26 = 64개였다. CPU 주소는 32비트 너비이므로, 태그 필드에 32 - 5 - 6 = 21비트가 필요했다.

오리지널 펜티엄 4 프로세서는 또한 256 KiB 크기의 8-방향 집합 연관 L2 통합 캐시를 가졌고, 캐시 블록 크기는 128바이트였다. 이는 태그 필드에 32 - 8 - 7 = 17비트가 필요하다는 것을 의미한다.

### 플래그 비트

명령어 캐시는 캐시 행 엔트리당 하나의 플래그 비트만 필요하다: 유효 비트. 유효 비트는 캐시 블록에 유효한 데이터가 로드되었는지 여부를 나타낸다.

전원이 켜지면 하드웨어는 모든 캐시의 모든 유효 비트를 "무효"로 설정한다. 일부 시스템은 다른 때에도 유효 비트를 "무효"로 설정하는데, 예를 들어 한 프로세서의 캐시에 있는 다중 마스터 버스 스누핑 하드웨어가 다른 프로세서에서 주소 브로드캐스트를 듣고 로컬 캐시의 특정 데이터 블록이 이제 오래되어 무효로 표시되어야 한다는 것을 인식할 때이다.

데이터 캐시는 일반적으로 캐시 라인당 두 개의 플래그 비트를 필요로 한다. 유효 비트와 더티 비트이다. 더티 비트가 설정되어 있다는 것은 관련 캐시 라인이 메인 메모리에서 읽은 이후로 변경되었다는 것("더티")을 나타내며, 이는 프로세서가 해당 라인에 데이터를 기록했고 새 값이 메인 메모리까지 완전히 전파되지 않았음을 의미한다.

## 캐시 미스

캐시 미스는 캐시의 데이터 조각을 읽거나 쓰는 데 실패하여 훨씬 긴 지연 시간을 가진 주 기억 장치 접근으로 이어지는 경우를 말한다. 캐시 미스에는 세 가지 종류가 있다: 명령어 읽기 미스, 데이터 읽기 미스, 데이터 쓰기 미스.

명령어 캐시에서 발생하는 캐시 읽기 미스는 일반적으로 가장 큰 지연을 유발한다. 왜냐하면 프로세서, 또는 적어도 실행 스레드가 주 기억 장치에서 명령어가 가져올 때까지 기다려야 하기(스톨) 때문이다. 데이터 캐시에서 발생하는 캐시 읽기 미스는 일반적으로 더 작은 지연을 유발한다. 왜냐하면 캐시 읽기에 의존하지 않는 명령어는 발행되어 데이터가 주 기억 장치에서 반환될 때까지 실행을 계속할 수 있고, 의존하는 명령어는 실행을 재개할 수 있기 때문이다. 데이터 캐시에 대한 캐시 쓰기 미스는 일반적으로 가장 짧은 지연을 유발한다. 왜냐하면 쓰기를 큐에 넣을 수 있고, 후속 명령어의 실행에는 거의 제한이 없기 때문이다. 프로세서는 큐가 가득 찰 때까지 계속 진행할 수 있다. 미스 유형에 대한 자세한 내용은 캐시 성능 측정 및 지표를 참조하라.

## 주소 변환

대부분의 범용 CPU는 어떤 형태의 가상 메모리를 구현한다. 요약하자면, 기계에서 실행되는 각 프로그램은 자체적으로 단순화된 주소 공간을 보며, 이 공간에는 해당 프로그램만의 코드와 데이터가 포함되거나, 모든 프로그램이 공통 가상 주소 공간에서 실행된다. 프로그램은 물리 주소 공간의 주소 대신 자체 가상 주소 공간의 주소를 계산, 비교, 읽기, 쓰기하여 실행되므로 프로그램이 더 간단하고 작성하기 쉬워진다.

가상 메모리는 프로세서가 프로그램에서 생성된 가상 주소를 주 기억 장치의 물리 주소로 변환하도록 요구한다. 이 변환을 수행하는 프로세서의 부분은 MMU로 알려져 있다. MMU를 통한 빠른 경로는 TLB에 저장된 변환을 수행할 수 있으며, 이는 운영 체제의 페이지 테이블, 세그먼트 테이블 또는 둘 다의 매핑 캐시이다.

현재 논의를 위해 주소 변환의 세 가지 중요한 특징이 있다.

* 지연 시간: 주소 생성기에서 가상 주소를 사용할 수 있게 된 후 얼마 후(아마 몇 사이클 후) MMU에서 물리 주소를 사용할 수 있게 된다.
* 에일리어싱: 여러 가상 주소가 하나의 물리 주소에 매핑될 수 있다. 대부분의 프로세서는 해당 단일 물리 주소에 대한 모든 업데이트가 프로그램 순서대로 발생함을 보장한다. 이 보장을 이행하기 위해 프로세서는 해당 시점에 캐시에 단 하나의 물리 주소 복사본만 존재하도록 해야 한다.
* 세분화: 가상 주소 공간은 페이지로 나뉘어져 있다. 예를 들어, 4 GiB 가상 주소 공간은 각각 독립적으로 매핑될 수 있는 4 KiB 크기의 1,048,576 페이지로 나뉠 수 있다. 여러 페이지 크기가 지원될 수 있다. 자세한 내용은 가상 메모리를 참조하라.

초기 가상 메모리 시스템 중 하나인 IBM M44/44X는 메인 메모리에 대한 모든 프로그램 접근 이전에 코어 메모리에 보관된 매핑 테이블에 접근해야 했다. 캐시가 없고, 매핑 테이블 메모리가 메인 메모리와 같은 속도로 작동하면 메모리 접근 속도가 절반으로 줄어든다. 매핑을 위해 메인 메모리에 페이지 테이블을 사용한 두 초기 머신인 IBM 시스템/360 모델 67과 GE 645는 모두 메모리 내 페이지 테이블 접근을 위한 캐시로 작은 연관 메모리를 가지고 있었다. 두 머신 모두 메인 메모리 캐시를 가진 최초의 머신인 IBM 시스템/360 모델 85보다 앞서 있었으므로, 컴퓨터 시스템에 사용된 최초의 하드웨어 캐시는 데이터 또는 명령어 캐시가 아니라 TLB였다.

캐시는 인덱스 또는 태그가 물리적 주소 또는 가상 주소에 해당하는지 여부에 따라 네 가지 유형으로 나눌 수 있다:

* 물리적으로 인덱싱되고 물리적으로 태그가 지정된 (PIPT) 캐시는 인덱스와 태그 모두에 물리적 주소를 사용한다. 이것은 간단하고 앨리어싱 문제를 피할 수 있지만, 해당 주소를 캐시에서 찾기 전에 물리적 주소를 찾아야 하므로 (TLB 미스와 메인 메모리 접근을 포함할 수 있음) 느리다.
* 가상으로 인덱싱되고 가상으로 태그가 지정된 (VIVT) 캐시는 인덱스와 태그 모두에 가상 주소를 사용한다. 이 캐싱 스킴은 주어진 가상 주소에 대한 물리적 주소를 결정하기 위해 MMU를 먼저 참조할 필요가 없으므로 훨씬 빠른 조회를 가능하게 한다. 그러나 VIVT는 여러 다른 가상 주소가 동일한 물리적 주소를 참조할 수 있는 앨리어싱 문제로 어려움을 겪는다. 결과적으로 이러한 주소는 동일한 메모리를 참조함에도 불구하고 별도로 캐시되어 일관성 문제를 야기한다. 이 문제에 대한 해결책이 존재하지만 표준 일관성 프로토콜에서는 작동하지 않는다. 또 다른 문제는 동일한 가상 주소가 여러 다른 물리적 주소에 매핑되는 동음이의어 문제이다. 이러한 매핑은 가상 인덱스 자체만으로는 구별할 수 없지만, 잠재적인 해결책에는 문맥 교환 후 캐시 플러시, 주소 공간을 겹치지 않게 강제, 주소 공간 ID(ASID)로 가상 주소 태그 지정 등이 포함된다. 또한 가상-물리적 매핑이 변경될 수 있으며, 이는 가상 주소가 더 이상 유효하지 않으므로 캐시 라인을 플러시해야 하는 문제가 있다. 태그가 물리적 주소(VIPT)를 사용하는 경우 이 모든 문제는 발생하지 않는다.
* 가상으로 인덱싱되고 물리적으로 태그가 지정된 (VIPT) 캐시는 인덱스에 가상 주소를 사용하고 태그에 물리적 주소를 사용한다. PIPT에 비해 장점은 대기 시간이 짧다는 것이다. 캐시 라인은 TLB 변환과 병렬로 조회될 수 있지만, 물리적 주소를 사용할 수 있을 때까지 태그를 비교할 수 없다. VIVT에 비해 장점은 태그에 물리적 주소가 있으므로 캐시가 동음이의어를 감지할 수 있다는 것이다. 이론적으로 VIPT는 가상 주소와 물리적 주소 사이에 일부 인덱스 비트가 다를 수 있고 (예: 4 KiB 페이지의 경우 비트 12 이상), 가상 인덱스와 물리적 태그 모두에 포함되어야 하므로 더 많은 태그 비트가 필요하다. 실제로는 일관성 문제를 피하기 위해 VIPT 캐시는 이러한 인덱스 비트가 없도록 설계되었으므로 (예: 4 KiB 페이지의 경우 인덱스와 블록 오프셋의 총 비트 수를 12로 제한) 문제가 되지 않는다. 이는 VIPT 캐시의 크기를 페이지 크기 \* 캐시의 연관성으로 제한한다.
* 물리적으로 인덱싱되고 가상으로 태그가 지정된 (PIVT) 캐시는 문헌에서 종종 쓸모없고 존재하지 않는다고 주장된다. 그러나 MIPS R6000은 유일한 알려진 구현으로 이 캐시 유형을 사용한다. R6000은 이미터-결합 논리로 구현되었는데, 이는 TLB와 같은 대용량 메모리에 적합하지 않은 매우 빠른 기술이다. R6000은 TLB 메모리를 2단계 캐시의 예약된 부분에 배치하고, 칩에 작고 빠른 TLB "슬라이스"를 가짐으로써 이 문제를 해결한다. 캐시는 TLB 슬라이스에서 얻은 물리적 주소로 인덱싱된다. 그러나 TLB 슬라이스는 캐시를 인덱싱하는 데 필요한 가상 주소 비트만 변환하고 태그를 사용하지 않으므로, 가상 주소로 태그를 지정하여 해결되는 잘못된 캐시 히트가 발생할 수 있다.

이 재귀의 속도 (부하 지연 시간)는 CPU 성능에 매우 중요하므로 대부분의 최신 레벨-1 캐시는 가상으로 인덱싱되어 MMU의 TLB 조회가 캐시 RAM에서 데이터를 가져오는 것과 병렬로 진행될 수 있도록 한다.

그러나 가상 인덱싱이 모든 캐시 레벨에 최적의 선택은 아니다. 가상 앨리어싱을 처리하는 비용은 캐시 크기에 따라 증가하며, 그 결과 대부분의 레벨-2 이상 캐시는 물리적으로 인덱싱된다.

캐시는 역사적으로 캐시 태그에 가상 및 물리적 주소 모두를 사용했지만, 가상 태그는 이제 일반적이지 않다. TLB 조회가 캐시 RAM 조회보다 먼저 완료될 수 있다면, 물리적 주소는 태그 비교에 제때 사용할 수 있으며, 가상 태그가 필요 없다. 따라서 대형 캐시는 물리적으로 태그가 지정되는 경향이 있으며, 작고 대기 시간이 매우 짧은 캐시만 가상으로 태그가 지정된다. 최근 범용 CPU에서는 가상 태그가 아래에 설명된 가상 힌트로 대체되었다.

### 동음이의어 및 동의어 문제

가상 인덱싱 및 태그 지정에 의존하는 캐시는 동일한 가상 주소가 다른 물리적 주소에 매핑된 후 (동형동음이의어) 불일치 상태가 되는데, 이는 태그 지정에 물리적 주소를 사용하거나 주소 공간 식별자를 캐시 라인에 저장하여 해결할 수 있다. 그러나 후자의 접근 방식은 여러 캐시 라인이 동일한 물리적 주소에 대한 데이터를 저장하게 되는 동의어 문제에는 도움이 되지 않는다. 이러한 위치에 쓰면 캐시의 한 위치만 업데이트되어 다른 위치에는 일관되지 않은 데이터가 남을 수 있다. 이 문제는 다른 주소 공간에 대해 겹치지 않는 메모리 레이아웃을 사용하거나, 그렇지 않으면 매핑이 변경될 때 캐시(또는 그 일부)를 플러시해야 한다.

### 가상 태그 및 힌트

가상 태그의 가장 큰 장점은 연관 캐시의 경우 가상-물리적 변환이 수행되기 전에 태그 일치가 진행될 수 있다는 것이다. 그러나 일관성 프로브 및 축출은 작업에 대한 물리적 주소를 제시한다. 하드웨어는 물리적 주소를 캐시 인덱스로 변환하는 어떤 수단을 가져야 하며, 일반적으로 물리적 태그뿐만 아니라 가상 태그도 저장한다. 비교하자면, 물리적으로 태그가 지정된 캐시는 가상 태그를 유지할 필요가 없으므로 더 간단하다. TLB에서 가상-물리적 매핑이 삭제되면 해당 가상 주소를 가진 캐시 엔트리는 어떤 식으로든 플러시되어야 한다. 또는 TLB에 의해 매핑되지 않은 페이지에 캐시 엔트리가 허용되는 경우, 해당 페이지의 접근 권한이 페이지 테이블에서 변경될 때 해당 엔트리는 플러시되어야 한다.

운영 체제가 캐시에 가상 앨리어스가 동시에 상주하지 않도록 보장하는 것도 가능하다. 운영 체제는 아래에 설명된 페이지 컬러링을 적용하여 이러한 보장을 제공한다. 일부 초기 RISC 프로세서(SPARC, RS/6000)는 이 접근 방식을 취했다. 가상 앨리어스 감지 및 축출에 대한 하드웨어 비용이 감소하고 완벽한 페이지 컬러링에 대한 소프트웨어 복잡성 및 성능 저하가 증가함에 따라 최근에는 사용되지 않았다.

연관 캐시에서 태그의 두 가지 기능을 구별하는 것이 유용할 수 있다: 엔트리 세트의 어떤 방식을 선택할지 결정하는 데 사용되며, 캐시 히트 또는 미스를 결정하는 데 사용된다. 두 번째 기능은 항상 정확해야 하지만, 첫 번째 기능은 추측하여 가끔 잘못된 답변을 얻는 것이 허용된다.

일부 프로세서(예: 초기 SPARC)는 가상 및 물리적 태그를 모두 가진 캐시를 가지고 있다. 가상 태그는 방식 선택에 사용되고, 물리적 태그는 히트 또는 미스 결정에 사용된다. 이러한 종류의 캐시는 가상 태그 캐시의 대기 시간 이점과 물리적 태그 캐시의 간단한 소프트웨어 인터페이스를 누린다. 그러나 태그가 중복되는 추가 비용이 발생한다. 또한 미스 처리 중에는 인덱싱된 캐시 라인의 대체 방식에 대해 가상 앨리어스를 탐색하고 일치하는 항목을 축출해야 한다.

추가 영역(및 일부 대기 시간)은 가상 태그 대신 각 캐시 엔트리와 함께 가상 힌트를 유지함으로써 완화될 수 있다. 이 힌트는 가상 태그의 하위 집합 또는 해시이며, 데이터를 가져올 캐시 방식을 선택하고 물리적 태그를 가져오는 데 사용된다. 가상 태그 캐시와 마찬가지로 가상 힌트 일치는 있지만 물리적 태그 불일치가 있을 수 있다. 이 경우 일치하는 힌트가 있는 캐시 엔트리는 축출되어야 한다. 이렇게 하면 이 주소에서 캐시를 채운 후의 캐시 접근은 하나의 힌트 일치만 갖게 된다. 가상 힌트는 가상 태그보다 서로 구별하는 비트 수가 적으므로 가상 힌트 캐시는 가상 태그 캐시보다 더 많은 충돌 미스를 겪는다.

아마도 가상 힌트의 궁극적인 감소는 펜티엄 4(윌라멧 및 노스우드 코어)에서 찾을 수 있을 것이다. 이 프로세서에서는 가상 힌트가 사실상 2비트이고 캐시는 4방향 세트 연관이다. 사실상 하드웨어는 가상 주소에서 캐시 인덱스로의 간단한 순열을 유지하여 가져온 네 가지 방식 중 올바른 것을 선택하는 데 CAM이 필요 없다.

### 페이지 컬러링

대형 물리적으로 인덱싱된 캐시(일반적으로 2차 캐시)는 문제에 봉착한다. 애플리케이션이 아니라 운영 체제가 캐시에서 어떤 페이지가 서로 충돌하는지를 제어한다. 한 프로그램 실행에서 다음 프로그램 실행으로 페이지 할당의 차이는 캐시 충돌 패턴의 차이를 야기하며, 이는 프로그램 성능에 매우 큰 차이를 가져올 수 있다. 이러한 차이는 벤치마크 실행에 대해 일관되고 반복 가능한 타이밍을 얻는 것을 매우 어렵게 만들 수 있다.

문제를 이해하기 위해 1 MiB 물리적으로 인덱싱된 직접 매핑된 2단계 캐시와 4 KiB 가상 메모리 페이지를 가진 CPU를 고려해보자. 순차적인 물리적 페이지는 캐시 내의 순차적인 위치에 매핑되며, 256개 페이지 이후에는 패턴이 반복된다. 우리는 각 물리적 페이지에 0-255의 색상을 부여하여 캐시 내에서 어디로 갈 수 있는지를 나타낼 수 있다. 다른 색상을 가진 물리적 페이지 내의 위치는 캐시에서 충돌할 수 없다.

캐시를 최대한 활용하려는 프로그래머는 프로그램의 접근 패턴을 조정하여 주어진 시간에 1 MiB의 데이터만 캐시되도록 하여 용량 미스를 방지할 수 있다. 그러나 그들은 접근 패턴에 충돌 미스가 없도록 해야 한다. 이 문제를 생각하는 한 가지 방법은 프로그램이 사용하는 가상 페이지를 나누고 물리적 페이지에 색상을 할당한 방식과 동일한 방식으로 가상 색상을 할당하는 것이다. 프로그래머는 코드의 접근 패턴을 조정하여 동일한 가상 색상을 가진 두 페이지가 동시에 사용되지 않도록 할 수 있다. 이러한 최적화(예: 루프 중첩 최적화)에 대한 광범위한 문헌이 있으며, 주로 고성능 컴퓨팅(HPC) 커뮤니티에서 비롯되었다.

문제는 주어진 순간에 사용 중인 모든 페이지가 다른 가상 색상을 가질 수 있지만, 일부는 동일한 물리적 색상을 가질 수 있다는 점이다. 실제로 운영 체제가 물리적 페이지를 가상 페이지에 무작위적이고 균일하게 할당하면 일부 페이지가 동일한 물리적 색상을 가질 가능성이 매우 높으며, 그런 다음 해당 페이지의 위치가 캐시에서 충돌할 것이다(이는 생일 역설이다).

해결책은 운영 체제가 다른 물리적 색상 페이지를 다른 가상 색상에 할당하려고 시도하는 것인데, 이 기술을 페이지 컬러링이라고 한다. 실제 가상에서 물리적 색상으로의 매핑은 시스템 성능과 관련이 없지만, 이상한 매핑은 추적하기 어렵고 이점이 거의 없으므로 대부분의 페이지 컬러링 접근 방식은 단순히 물리적 및 가상 페이지 색상을 동일하게 유지하려고 시도한다.

운영 체제가 각 물리적 페이지가 하나의 가상 색상에만 매핑된다고 보장할 수 있다면, 가상 앨리어싱이 없으며 프로세서는 미스 처리 중에 추가 가상 앨리어스 프로브가 필요 없이 가상으로 인덱싱된 캐시를 사용할 수 있다. 또는 OS는 가상 색상이 변경될 때마다 캐시에서 페이지를 플러시할 수 있다. 위에서 언급했듯이 이 접근 방식은 일부 초기 SPARC 및 RS/6000 설계에 사용되었다.

소프트웨어 페이지 컬러링 기술은 멀티코어 프로세서에서 공유 라스트 레벨 캐시(LLC)를 효과적으로 분할하는 데 사용되었다. 멀티코어 프로세서에서 이러한 운영 체제 기반 LLC 관리는 인텔에 의해 채택되었다.

## 현대 프로세서의 캐시 계층 구조

AMD 불도저 서버의 메모리 계층 구조
최신 프로세서는 여러 개의 상호 작용하는 온칩 캐시를 가지고 있다. 특정 캐시의 작동은 캐시 크기, 캐시 블록 크기, 세트 내 블록 수, 캐시 세트 교체 정책 및 캐시 쓰기 정책(쓰루 또는 백)으로 완전히 지정할 수 있다.

특정 캐시의 모든 캐시 블록은 동일한 크기와 동일한 연관성을 가지지만, 일반적으로 "고수준" 캐시(레벨 1 캐시라고 함)는 블록 수가 적고, 블록 크기가 작으며, 세트 내 블록 수가 적지만 접근 시간이 매우 짧다. "저수준" 캐시(즉, 레벨 2 이하)는 점진적으로 더 많은 블록 수, 더 큰 블록 크기, 세트 내 더 많은 블록을 가지며, 상대적으로 더 긴 접근 시간을 가지지만, 여전히 메인 메모리보다 훨씬 빠르다.

캐시 엔트리 교체 정책은 프로세서 설계자가 구현하도록 선택한 캐시 알고리즘에 의해 결정된다. 어떤 경우에는 다양한 종류의 작업 부하에 대해 여러 알고리즘이 제공된다.

### 특수화된 캐시

파이프라인 CPU는 파이프라인의 여러 지점(명령어 인출, 가상-물리적 주소 변환 및 데이터 인출)에서 메모리에 접근한다(클래식 RISC 파이프라인 참조). 자연스러운 설계는 이러한 각 지점에 대해 서로 다른 물리적 캐시를 사용하는 것이다. 이렇게 하면 단일 물리적 리소스가 파이프라인의 두 지점에 서비스를 제공하기 위해 스케줄링될 필요가 없다. 따라서 파이프라인은 자연스럽게 최소 세 개의 별도 캐시(TLB 명령 및 데이터)를 가지게 되며, 각 캐시는 특정 역할에 특화되어 있다.

#### 희생자 캐시

**희생자 캐시**는 CPU 캐시에서 교체 시 축출된 블록을 보관하는 데 사용되는 캐시이다. 희생자 캐시는 메인 캐시와 재충전 경로 사이에 위치하며, 메인 캐시에서 축출된 데이터 블록만 보관한다. 희생자 캐시는 일반적으로 완전 연관 캐시이며, 충돌 미스 수를 줄이는 것을 목표로 한다. 일반적으로 사용되는 많은 프로그램은 모든 접근에 대해 연관 매핑을 요구하지 않는다. 실제로 프로그램 메모리 접근의 극히 일부만이 높은 연관성을 요구한다. 희생자 캐시는 이러한 접근에만 높은 연관성을 제공하여 이 속성을 활용한다. 이 캐시는 1990년 DEC의 노먼 주피가 도입했다.

인텔의 하스웰 프로세서의 크리스털웰 변형은 온-패키지 128 MiB EDRAM 레벨 4 캐시를 도입하여 프로세서의 레벨 3 캐시의 희생자 캐시 역할을 한다. 스카이레이크 마이크로아키텍처에서는 레벨 4 캐시가 더 이상 희생자 캐시로 작동하지 않는다.

#### 트레이스 캐시

캐시 특수화의 가장 극단적인 예 중 하나는 인텔 펜티엄 4 마이크로프로세서에서 발견되는 **트레이스 캐시**(실행 트레이스 캐시라고도 함)이다. 트레이스 캐시는 이미 인출되고 디코딩된 명령어의 트레이스를 저장함으로써 명령어 인출 대역폭을 늘리고 전력 소비를 줄이는(펜티엄 4의 경우) 메커니즘이다.

트레이스 캐시는 명령어가 디코딩된 후 또는 명령어가 퇴역될 때 명령어를 저장한다. 일반적으로 명령어는 개별 기본 블록 또는 동적 명령어 트레이스를 나타내는 그룹으로 트레이스 캐시에 추가된다. 펜티엄 4의 트레이스 캐시는 x86 명령어를 디코딩한 결과인 마이크로 오퍼레이션을 저장하며, 마이크로 오퍼레이션 캐시의 기능도 제공한다. 이를 통해 다음 번에 명령어가 필요할 때 다시 마이크로 오퍼레이션으로 디코딩할 필요가 없다.

#### 쓰기 통합 캐시 (WCC)

쓰기 통합 캐시(Write Coalescing Cache)는 AMD의 불도저 마이크로아키텍처에서 L2 캐시의 일부인 특수 캐시이다. 모듈의 두 L1D 캐시에서 발생한 저장 작업은 WCC를 통해 진행되며, 여기서 버퍼링되고 통합된다. WCC의 임무는 L2 캐시에 대한 쓰기 횟수를 줄이는 것이다.

#### 마이크로-오퍼레이션 (μop 또는 uop) 캐시

**마이크로-오퍼레이션 캐시**(**μop 캐시**, **uop 캐시** 또는 **UC**)는 디코딩된 명령어의 마이크로 오퍼레이션을 직접 명령어 디코더나 명령어 캐시에서 받아 저장하는 특수 캐시이다. 명령어를 디코딩해야 할 때, μop 캐시에서 디코딩된 형태를 확인하여 캐시되어 있으면 재사용한다. 만약 사용 불가능하면, 명령어는 디코딩되어 캐시된다.

P6 프로세서 제품군을 위한 대체 프런트엔드로서 μop 캐시를 설명하는 초기 연구 중 하나는 2001년 논문 "Micro-Operation Cache: A Power Aware Frontend for Variable Instruction Length ISA"이다. 이후 인텔은 샌디브리지 프로세서와 아이비브리지, 하스웰과 같은 후속 마이크로아키텍처에 μop 캐시를 포함했다. AMD는 젠 마이크로아키텍처에 μop 캐시를 구현했다.

완전히 사전 디코딩된 명령어를 가져오는 것은 가변 길이의 복잡한 명령어를 더 간단한 고정 길이 마이크로-오퍼레이션으로 반복적으로 디코딩할 필요를 없애고, 가져온 명령어를 예측, 가져오기, 회전 및 정렬하는 과정을 단순화한다. μop 캐시는 효과적으로 가져오기 및 디코딩 하드웨어의 부하를 덜어주어 전력 소비를 줄이고 디코딩된 마이크로-오퍼레이션의 프런트엔드 공급을 개선한다. μop 캐시는 또한 디코딩된 마이크로-오퍼레이션을 백엔드에 더 일관되게 전달하고 CPU의 가져오기 및 디코딩 논리의 다양한 병목 현상을 제거함으로써 성능을 향상시킨다.

μop 캐시는 트레이스 캐시와 많은 유사점을 가지고 있지만, μop 캐시가 훨씬 더 간단하여 전력 효율성이 더 좋다. 이는 배터리 구동 장치에 구현하는 데 더 적합하다. 트레이스 캐시의 주요 단점은 전력 비효율성으로 이어지는데, 이는 동적으로 생성된 명령어 트레이스를 캐싱하고 재사용하는 휴리스틱을 결정하는 데 필요한 하드웨어 복잡성 때문이다.

#### 분기 대상 명령어 캐시

ARM 마이크로프로세서에서 사용되는 이름인 **분기 대상 캐시** 또는 **분기 대상 명령어 캐시**는 수행된 분기 대상의 첫 몇 명령어를 저장하는 특수 캐시이다. 이는 일반 명령어 캐시가 필요 없는 저전력 프로세서에 사용되는데, 메모리 시스템이 CPU를 만족시킬 만큼 충분히 빠르게 명령어를 제공할 수 있기 때문이다. 그러나 이는 순차적인 명령어에만 해당된다. 새로운 주소에서 명령어 인출을 다시 시작하는 데는 여전히 몇 사이클의 지연 시간이 소요되어 제어 전송 후 몇 사이클의 파이프라인 버블이 발생한다. 분기 대상 캐시는 이러한 몇 사이클 동안 명령어를 제공하여 대부분의 분기 후 지연을 방지한다.

이는 전통적인 풀타임 명령어 캐시보다 훨씬 작은 캐시로도 최고 속도 작동을 가능하게 한다.

#### 스마트 캐시

**스마트 캐시**는 인텔이 개발한 여러 실행 코어를 위한 레벨 2 또는 레벨 3 캐싱 방식이다.

스마트 캐시는 멀티 코어 프로세서의 코어들 간에 실제 캐시 메모리를 공유한다. 코어들이 캐시 공간의 동일한 부분을 필요로 하지 않을 때 전용 코어별 캐시에 비해 전체 캐시 미스율이 감소한다. 결과적으로 다른 코어들이 비활성 상태일 때 단일 코어는 전체 레벨 2 또는 레벨 3 캐시를 사용할 수 있다. 또한 공유 캐시는 서로 다른 실행 코어 간에 메모리를 공유하는 속도를 높인다.

### 멀티레벨 캐시

또 다른 문제는 캐시 지연 시간과 히트율 간의 근본적인 트레이드오프이다. 캐시가 클수록 히트율은 좋아지지만 지연 시간은 길어진다. 이 트레이드오프를 해결하기 위해 많은 컴퓨터는 더 크고 느린 캐시에 의해 지원되는 작고 빠른 캐시를 사용하여 여러 수준의 캐시를 사용한다. 다단계 캐시는 일반적으로 가장 빠르지만 가장 작은 캐시인 레벨 1(**L1**)을 먼저 확인하는 방식으로 작동한다. 히트하면 프로세서는 고속으로 진행된다. 이 캐시가 미스하면 더 느리지만 더 큰 다음 수준 캐시인 레벨 2(**L2**)를 확인하고, 외부 메모리에 접근하기 전에 계속해서 확인한다.

메인 메모리와 가장 빠른 캐시 사이의 지연 시간 차이가 커지면서 일부 프로세서는 최대 3단계의 온칩 캐시를 활용하기 시작했다. 가격에 민감한 설계는 이를 사용하여 전체 캐시 계층을 온칩으로 가져왔지만, 2010년대에는 일부 최고 성능 설계가 대형 오프칩 캐시를 다시 사용하기 시작했으며, 이는 종종 EDRAM으로 구현되고 멀티칩 모듈에 장착되어 4단계 캐시 역할을 한다. IBM z15 (2019)와 같은 메인프레임 CPU의 경우와 같이 드물게 L1까지 모든 레벨이 EDRAM으로 구현되어 SRAM을 완전히 대체한다(캐시의 경우 SRAM은 여전히 레지스터에 사용됨). 애플의 ARM 기반 애플 실리콘 시리즈는 A14 및 M1부터 고성능 코어 각각에 대해 192 KiB L1i 캐시를 가지는데, 이는 비정상적으로 큰 양이다. 그러나 고효율 코어는 128 KiB만 가진다. 이후 인텔의 루나레이크 및 퀄컴의 Oryon과 같은 다른 프로세서도 유사한 L1i 캐시 크기를 구현했다.

L3 및 L4 캐시의 이점은 애플리케이션의 접근 패턴에 따라 달라진다. L3 및 L4 캐시를 통합한 제품의 예는 다음과 같다.

* 알파 21164 (1995)는 1~64 MiB의 오프칩 L3 캐시를 가졌다.
* AMD K6-III (1999)는 마더보드 기반 L3 캐시를 가졌다.
* IBM POWER4 (2001)는 프로세서당 32 MiB의 오프칩 L3 캐시를 가졌으며, 여러 프로세서 간에 공유되었다.
* 이태니엄 2 (2003)는 온다이 6 MiB 통합 레벨 3 (L3) 캐시를 가졌다. 이태니엄 2 (2003) MX 2 모듈은 두 개의 이태니엄 2 프로세서와 공유 64 MiB L4 캐시를 멀티칩 모듈에 통합하여 매디슨 프로세서와 핀 호환되었다.
* 인텔의 제온 MP 제품 코드명 "툴사" (2006)는 두 프로세서 코어 간에 공유되는 16 MiB 온다이 L3 캐시를 특징으로 한다.
* AMD 페넘 (2007)은 2 MiB L3 캐시를 가졌다.
* 페넘 II (2008)는 최대 6 MiB 온다이 통합 L3 캐시를 가졌다.
* 인텔 코어 i7 (2008)은 모든 코어에서 공유되는 8 MiB 온다이 통합 L3 캐시를 가졌다.
* 하스웰 CPU 중 Intel Iris Pro Graphics가 통합된 모델은 128 MiB의 eDRAM을 사실상 L4 캐시로 사용한다.

마지막으로 메모리 계층의 다른 끝에서 CPU 레지스터 파일 자체는 시스템에서 가장 작고 빠른 캐시로 간주될 수 있으며, 특별한 특징은 소프트웨어(일반적으로 컴파일러에 의해, 예를 들어 루프 중첩 최적화를 위해 주 메모리에서 검색된 값을 저장하기 위해 레지스터를 할당할 때)로 스케줄링된다는 것이다. 그러나 레지스터 이름 변경을 사용하면 대부분의 컴파일러 레지스터 할당은 런타임에 하드웨어에 의해 레지스터 뱅크로 동적으로 재할당되어 CPU가 잘못된 데이터 종속성을 깨고 파이프라인 위험을 완화할 수 있다.

레지스터 파일도 때로는 계층 구조를 가진다: 크레이-1 (1976년경)은 일반적으로 사용할 수 있는 8개의 주소 "A" 및 8개의 스칼라 데이터 "S" 레지스터를 가졌다. 또한 접근하는 데 시간이 더 오래 걸리지만 주 메모리보다 빠른 64개의 주소 "B" 및 64개의 스칼라 데이터 "T" 레지스터 세트도 있었다. "B" 및 "T" 레지스터는 크레이-1에 데이터 캐시가 없었기 때문에 제공되었다. (크레이-1은 그러나 명령어 캐시를 가졌다.)

#### 멀티코어 칩

멀티 코어 칩을 고려할 때, 캐시를 공유해야 하는지 아니면 각 코어에 로컬이어야 하는지에 대한 의문이 있다. 공유 캐시를 구현하면 필연적으로 더 많은 배선과 복잡성이 발생한다. 그러나 코어당 하나의 캐시가 아니라 칩당 하나의 캐시를 가지면 필요한 공간의 양이 크게 줄어들어 더 큰 캐시를 포함할 수 있다.

일반적으로 L1 캐시를 공유하는 것은 바람직하지 않다. 결과적으로 지연 시간이 증가하여 각 코어가 싱글 코어 칩보다 상당히 느리게 실행될 수 있기 때문이다. 그러나 메모리에 접근하기 전에 호출되는 최하위 수준 캐시의 경우, 여러 가지 이유로 전역 캐시를 갖는 것이 바람직하다. 예를 들어 단일 코어가 전체 캐시를 사용할 수 있게 하고, 서로 다른 프로세스 또는 스레드가 캐시된 데이터를 공유할 수 있도록 하여 데이터 중복을 줄이며, 사용되는 캐시 일관성 프로토콜의 복잡성을 줄일 수 있다. 예를 들어, 3단계의 8코어 칩은 각 코어에 L1 캐시, 각 코어 쌍에 중간 L2 캐시, 모든 코어 간에 공유되는 L3 캐시를 포함할 수 있다.

메모리에 접근하기 전에 호출되는 공유 최하위 캐시는 일반적으로 마지막 수준 캐시(LLC)라고 불린다. LLC가 여러 코어 간에 공유될 때 병렬 처리 수준을 높이기 위해 추가 기술이 사용되는데, 여기에는 LLC를 여러 조각으로 나누어 특정 메모리 주소 범위를 지정하고 독립적으로 접근할 수 있도록 하는 것이 포함된다.

#### 분리형 대 통합형

분리형 캐시 구조에서는 명령어와 데이터가 별도로 캐시되므로 캐시 라인은 명령어 또는 데이터 중 하나만 캐시하는 데 사용된다. 분리형 데이터 및 명령어 변환 색인 버퍼를 사용하면 다양한 이점이 입증되었다. 통합 구조에서는 이러한 제약이 없으며 캐시 라인은 명령어와 데이터 모두를 캐시하는 데 사용될 수 있다.

#### 배타적 대 포괄적

다단계 캐시는 새로운 설계 결정을 도입한다. 예를 들어, 일부 프로세서에서는 L1 캐시의 모든 데이터가 L2 캐시에 어딘가에 있어야 한다. 이러한 캐시를 엄격히 포괄적이라고 한다. 다른 프로세서(AMD 애슬론 등)는 배타적 캐시를 가지고 있다: 데이터는 L1 및 L2 캐시 중 최대 하나에만 존재하며, 둘 다에는 존재하지 않는다. 아직 다른 프로세서(인텔 펜티엄 II, III, 4 등)는 L1 캐시의 데이터가 L2 캐시에 있어야 한다고 요구하지는 않지만, 종종 그렇다. 이 중간 정책에 대한 보편적으로 받아들여지는 이름은 없다. 두 가지 일반적인 이름은 "비배타적"과 "부분적으로 포괄적"이다.

배타적 캐시의 장점은 더 많은 데이터를 저장한다는 것이다. 이 장점은 배타적 L1 캐시가 L2 캐시와 비슷할 때 더 크고, L2 캐시가 L1 캐시보다 훨씬 클 때는 감소한다. L1이 미스하고 L2가 접근에 히트하면 L2의 히트 캐시 라인은 L1의 라인과 교환된다. 이 교환은 포괄적 캐시가 하는 것처럼 단순히 L2에서 L1으로 라인을 복사하는 것보다 훨씬 더 많은 작업이다.

엄격하게 포괄적인 캐시의 한 가지 장점은 멀티프로세서 시스템의 외부 장치나 다른 프로세서가 프로세서에서 캐시 라인을 제거하려고 할 때, 프로세서가 L2 캐시만 확인하면 된다는 것이다. 포괄성을 강제하지 않는 캐시 계층에서는 L1 캐시도 확인해야 한다. 단점으로는 L1과 L2 캐시의 연관성 사이에 상관관계가 있다는 것이다. L2 캐시가 모든 L1 캐시를 합친 것만큼의 웨이를 갖지 않으면 L1 캐시의 유효 연관성이 제한된다. 포괄적인 캐시의 또 다른 단점은 L2 캐시에서 축출이 발생할 때마다 (가능하다면) L1의 해당 라인도 포괄성을 유지하기 위해 축출되어야 한다는 것이다. 이는 상당한 작업이며 더 높은 L1 미스율을 초래할 것이다.

포괄적인 캐시의 또 다른 장점은 더 큰 캐시가 더 큰 캐시 라인을 사용할 수 있어 2차 캐시 태그의 크기를 줄일 수 있다는 것이다. (배타적 캐시는 L1 미스, L2 히트 시 캐시 라인을 교환할 수 있도록 두 캐시가 동일한 크기의 캐시 라인을 가져야 한다.) 2차 캐시가 1차 캐시보다 한 자릿수 더 크고 캐시 데이터가 캐시 태그보다 한 자릿수 더 크다면, 이 태그 영역 절약은 L2에 L1 캐시 데이터를 저장하는 데 필요한 추가 영역과 비슷할 수 있다.

### 스크래치패드 메모리

스크래치패드 메모리(SPM)는 컴퓨터 용어로 스크래치패드, 스크래치패드 RAM 또는 로컬 저장소라고도 알려져 있으며, 계산, 데이터 및 기타 진행 중인 작업을 임시로 저장하는 데 사용되는 고속 내부 메모리이다.

### 예시: K8

특수화와 다단계 캐싱을 모두 설명하기 위해 AMD 애슬론 64 CPU의 K8 코어의 캐시 계층 구조를 나타낸다.

AMD 애슬론 64 CPU의 K8 코어 캐시 계층 구조
K8에는 4개의 특수화된 캐시가 있다: 명령어 캐시, 명령어 TLB, 데이터 TLB, 데이터 캐시. 이 캐시들은 각각 특수화되어 있다.

* 명령어 캐시는 64바이트 메모리 라인의 복사본을 유지하고, 매 주기마다 16바이트를 가져온다. 이 캐시의 각 바이트는 8비트 대신 10비트로 저장되며, 추가 비트는 명령어의 경계를 표시한다(이는 사전 디코딩의 예이다). 캐시는 ECC 대신 패리티 보호만 가지고 있다. 패리티가 더 작고 손상된 데이터는 메모리에서 가져온 새 데이터로 대체될 수 있기 때문이다(메모리에는 항상 최신 명령어 복사본이 있음).
* 명령어 TLB는 페이지 테이블 엔트리(PTE)의 복사본을 유지한다. 매 사이클의 명령어 인출은 이 TLB를 통해 가상 주소를 물리 주소로 변환한다. 각 엔트리는 메모리에서 4바이트 또는 8바이트이다. K8은 가변 페이지 크기를 가지므로 각 TLB는 두 섹션으로 나뉘며, 하나는 4 KiB 페이지를 매핑하는 PTE를 유지하고, 다른 하나는 4 MiB 또는 2 MiB 페이지를 매핑하는 PTE를 유지한다. 이 분할은 각 섹션의 완전 연관 일치 회로를 더 간단하게 만든다. 운영 체제는 가상 주소 공간의 다른 섹션을 다른 크기의 PTE로 매핑한다.
* 데이터 TLB는 동일한 엔트리를 유지하는 두 개의 복사본을 가지고 있다. 두 복사본은 매 사이클마다 두 개의 데이터 접근이 가상 주소를 물리 주소로 변환할 수 있도록 한다. 명령어 TLB와 마찬가지로 이 TLB는 두 가지 종류의 엔트리로 나뉜다.
* 데이터 캐시는 64바이트 메모리 라인의 복사본을 보관한다. 이 캐시는 8개의 뱅크(각각 8 KiB의 데이터를 저장)로 나뉘며, 서로 다른 뱅크에 있는 한 매 주기마다 두 개의 8바이트 데이터를 가져올 수 있다. 태그는 두 개의 복사본을 가지고 있는데, 이는 각 64바이트 라인이 8개의 뱅크에 분산되어 있기 때문이다. 각 태그 복사본은 매 주기마다 두 개의 접근 중 하나를 처리한다.

K8은 또한 다단계 캐시를 가지고 있다. 2단계 명령어 및 데이터 TLB가 있으며, 이들은 4 KiB만 매핑하는 PTE를 저장한다. 명령어 및 데이터 캐시와 다양한 TLB는 대형 **통합** L2 캐시에서 채워질 수 있다. 이 캐시는 L1 명령어 및 데이터 캐시 모두에 대해 배타적인데, 이는 어떤 8바이트 라인도 L1 명령어 캐시, L1 데이터 캐시 또는 L2 캐시 중 하나에만 존재할 수 있음을 의미한다. 그러나 데이터 캐시의 라인이 TLB 중 하나에도 있는 PTE를 가질 수 있다. 운영 체제는 메모리의 페이지 테이블이 업데이트될 때 TLB의 일부를 플러시하여 TLB를 일관성 있게 유지할 책임이 있다.

K8은 또한 메모리에 절대 저장되지 않는 정보, 즉 예측 정보를 캐시한다. 이 캐시들은 위 다이어그램에는 표시되지 않는다. 이 종류의 CPU에서 흔히 볼 수 있듯이 K8은 상당히 복잡한 분기 예측을 가지고 있으며, 분기가 수행될지 여부를 예측하는 데 도움이 되는 테이블과 분기 및 점프의 대상을 예측하는 다른 테이블을 가지고 있다. 이 정보 중 일부는 L1 명령어 캐시와 통합 2차 캐시 모두에서 명령어와 연관되어 있다.

K8은 2차 캐시의 명령어와 예측 정보를 저장하는 흥미로운 트릭을 사용한다. 2차 캐시의 라인은 데이터 또는 명령어 1차 캐시에서 축출되었는지 여부에 따라 ECC 또는 패리티로 우발적인 데이터 손상(예: 알파 입자 충돌)으로부터 보호된다. 패리티 코드가 ECC 코드보다 적은 비트를 차지하므로 명령어 캐시의 라인에는 몇 개의 여유 비트가 있다. 이 비트는 해당 명령어와 관련된 분기 예측 정보를 캐시하는 데 사용된다. 그 결과 분기 예측기는 더 큰 유효 이력 테이블을 가지게 되어 정확도가 향상된다.

### 더 많은 계층 구조

다른 프로세서에는 다른 종류의 예측기(예: DEC 알파 21264의 저장-로드 우회 예측기)가 있으며, 다양한 특수 예측기가 미래 프로세서에서 더욱 번성할 것으로 예상된다.

이러한 예측기들은 계산 비용이 많이 드는 정보를 저장한다는 점에서 캐시이다. 예측기를 논할 때 사용되는 일부 용어는 캐시와 동일하다(분기 예측기에서 '히트'를 말한다). 그러나 예측기는 일반적으로 캐시 계층의 일부로 간주되지 않는다.

K8은 명령어 및 데이터 캐시를 하드웨어에서 **일관성** 있게 유지한다. 이는 저장 명령어 직후의 명령어에 대한 저장 작업이 그 다음 명령어를 변경할 것임을 의미한다. 알파 및 MIPS 제품군과 같은 다른 프로세서들은 소프트웨어에 의존하여 명령어 캐시를 일관성 있게 유지했다. 프로그램이 일관성을 보장하기 위해 운영 체제 기능을 호출하기 전까지는 저장 작업이 명령어 스트림에 나타나도록 보장되지 않는다.

### 태그 램

인텔 펜티엄 III 보드의 태그 RAM
컴퓨터 공학에서 태그 RAM은 CPU 캐시에 현재 저장된 가능한 메모리 위치 중 어느 것인지 지정하는 데 사용된다. 간단한 직접 매핑 설계에는 빠른 SRAM을 사용할 수 있다. 더 높은 연관 캐시는 일반적으로 내용 주소화 기억장치를 사용한다.

## 구현

캐시 **읽기**는 단일 주기 이상이 소요되는 가장 흔한 CPU 연산이다. 프로그램 실행 시간은 레벨-1 데이터 캐시 히트의 지연 시간에 매우 민감한 경향이 있다. 캐시를 가능한 한 빠르게 만들기 위해 많은 설계 노력과 종종 전력 및 실리콘 면적이 소모된다.

가장 간단한 캐시는 가상으로 인덱싱된 직접 매핑 캐시이다. 가상 주소는 가산기로 계산되고, 주소의 관련 부분이 추출되어 SRAM을 인덱싱하는 데 사용되며, SRAM은 로드된 데이터를 반환한다. 데이터는 바이트 시프터에서 바이트 정렬되고, 거기서부터 다음 연산으로 우회된다. 내부 루프에서는 태그 확인이 필요 없다. 사실 태그를 읽을 필요조차 없다. 파이프라인의 후반부에서, 그러나 로드 명령어가 폐기되기 전에, 로드된 데이터의 태그를 읽고 가상 주소와 비교하여 캐시 히트가 있었는지 확인해야 한다. 미스 시에는 요청된 캐시 라인으로 캐시가 업데이트되고 파이프라인이 다시 시작된다.

연관 캐시는 캐시의 어떤 항목을 선택할지 결정하기 위해 어떤 형태의 태그를 읽어야 하므로 더 복잡하다. N-방향 집합 연관 레벨-1 캐시는 일반적으로 모든 N개의 가능한 태그와 N개의 데이터를 병렬로 읽은 다음 일치하는 태그와 연관된 데이터를 선택한다. 레벨-2 캐시는 태그를 먼저 읽어서 데이터 SRAM에서 하나의 데이터 요소만 읽히도록 하여 전력을 절약하기도 한다.

2방향 연관 캐시의 읽기 경로
인접한 다이어그램은 주소의 다양한 필드가 사용되는 방식을 명확히 하기 위한 것이다. 주소 비트 31은 최상위 비트이고, 비트 0은 최하위 비트이다. 다이어그램은 4 KiB, 2방향 세트 연관, 가상 인덱싱 및 가상 태그 캐시의 SRAM, 인덱싱 및 멀티플렉싱을 보여준다. 이 캐시는 64바이트(B) 라인, 32비트 읽기 너비 및 32비트 가상 주소를 갖는다.

캐시가 4 KiB이고 64바이트 라인을 가지고 있으므로 캐시에는 64개의 라인만 있고, 32개의 행을 가진 태그 SRAM에서 한 번에 2개씩 읽는다. 각 행은 21비트 태그 쌍을 가지고 있다. 가상 주소 비트 31부터 6까지의 어떤 함수도 태그 및 데이터 SRAM을 인덱싱하는 데 사용될 수 있지만, 최하위 비트를 사용하는 것이 가장 간단하다.

마찬가지로, 캐시가 4 KiB이고 4 바이트 읽기 경로를 가지며, 각 접근에 대해 두 가지 방식을 읽기 때문에 데이터 SRAM은 512 행 × 8 바이트 너비이다.

보다 현대적인 캐시는 16 KiB, 4-way set-associative, 가상 인덱싱, 가상 힌트, 물리적 태그 방식일 수 있으며, 32 바이트 라인, 32비트 읽기 폭 및 36비트 물리 주소를 가질 수 있다. 이러한 캐시의 읽기 경로 재귀는 위 경로와 매우 유사하다. 태그 대신 가상 힌트를 읽고 가상 주소의 하위 집합과 일치시킨다. 파이프라인 후반부에서 가상 주소는 TLB에 의해 물리 주소로 변환되고 물리 태그가 읽혀진다(가상 힌트가 읽을 캐시 방식을 제공하므로 하나만 읽음). 마지막으로 물리 주소는 물리 태그와 비교되어 히트가 발생했는지 여부를 결정한다.

일부 SPARC 설계는 가상 가산기를 SRAM 디코더에 통합하여 L1 캐시의 속도를 몇 게이트 지연만큼 향상시켰다. 합 주소 지정 디코더를 참조하라.

### 역사

캐시 기술의 초기 역사는 가상 메모리의 발명 및 사용과 밀접하게 연결되어 있다. 반도체 메모리의 부족과 비용 때문에 1960년대 초기의 메인프레임 컴퓨터는 프로그램에서 사용하는 평평한 가상 메모리 공간에 매핑된 복잡한 물리적 메모리 계층 구조를 사용했다. 메모리 기술은 반도체, 자기 코어, 드럼, 디스크에 걸쳐 있었다. 프로그램에서 보고 사용하는 가상 메모리는 평평할 것이고, 캐싱은 프로세서 접근에 앞서 가장 빠른 메모리로 데이터와 명령어를 가져오는 데 사용될 것이다. 캐시 크기를 최적화하기 위해 광범위한 연구가 수행되었다. 최적 값은 사용된 프로그래밍 언어에 크게 의존하는 것으로 밝혀졌으며, Algol은 가장 작은 캐시 크기를 필요로 하고 Fortran과 Cobol은 가장 큰 캐시 크기를 필요로 했다.

마이크로컴퓨터 기술의 초기에는 메모리 접근이 프로세서 레지스터 접근보다 약간 느릴 뿐이었다. 그러나 1980년대 이후 프로세서와 메모리 사이의 성능 격차가 커지고 있다. 마이크로프로세서는 메모리보다 훨씬 빠르게 발전했으며, 특히 작동 진동수 측면에서 그러했다. 따라서 메모리는 성능 병목 현상이 되었다. 모든 메인 메모리를 CPU만큼 빠르게 만드는 것이 기술적으로 가능했지만, 더 경제적으로 실현 가능한 경로가 선택되었다. 즉, 많은 저속 메모리를 사용하지만, 성능 격차를 완화하기 위해 작고 고속의 캐시 메모리도 도입하는 것이다. 이는 동일한 가격으로 약 10배 더 많은 용량을 제공했으며, 결합된 성능은 약간만 감소했다.

#### 첫 번째 TLB 구현

TLB의 첫 번째 문서화된 사용은 GE 645와 IBM 360/67이었다. 둘 다 연관 메모리를 TLB로 사용했다.

#### 첫 번째 명령어 캐시

명령어 캐시의 첫 번째 문서화된 사용은 CDC 6600에서였다.

#### 첫 데이터 캐시

데이터 캐시의 첫 번째 문서화된 사용은 IBM 시스템/360 모델 85에서였다.

#### 68k 마이크로프로세서에서

1982년 출시된 68010은 두 명령어만으로 구성된 루프를 가속화하는 작고 특수한 명령어 캐시로 간주될 수 있는 "루프 모드"를 가지고 있다. 1984년 출시된 68020은 이를 256바이트의 일반적인 명령어 캐시로 대체하여 온칩 캐시 메모리를 탑재한 최초의 68k 시리즈 프로세서가 되었다.

1987년에 출시된 68030은 기본적으로 68020 코어에 추가 256바이트 데이터 캐시, 온칩 MMU, 공정 축소 및 캐시를 위한 버스트 모드가 추가된 것이다.

1990년에 출시된 68040은 각각 4킬로바이트의 분할된 명령어 및 데이터 캐시를 가지고 있다.

1994년 출시된 68060은 다음과 같다: 8 KiB 데이터 캐시(4방향 연관), 8 KiB 명령어 캐시(4방향 연관), 96바이트 FIFO 명령어 버퍼, 256엔트리 분기 캐시, 64엔트리 주소 변환 캐시 MMU 버퍼(4방향 연관).

#### x86 마이크로프로세서에서

i386 마이크로프로세서 (33 MHz), 64 KiB 캐시 (25 ns; 왼쪽 하단에 8개 칩), 2 MiB DRAM (70 ns; 캐시 오른쪽에 8개 SIMM), 캐시 컨트롤러 (오스텍 A38202; 프로세서 오른쪽에 위치)가 장착된 마더보드의 예시
x86 마이크로프로세서가 386에서 20 MHz 이상의 클럭 속도에 도달하면서, 성능 향상을 위해 소량의 빠른 캐시 메모리가 시스템에 탑재되기 시작했다. 이는 주 메모리에 사용되는 DRAM이 최대 120 ns의 상당한 지연 시간과 새로고침 주기를 가졌기 때문이다. 캐시는 당시 10~25 ns 정도의 지연 시간을 가졌던 더 비싸지만 훨씬 빠른 SRAM 메모리 셀로 구성되었다. 초기 캐시는 프로세서 외부에 있었고 일반적으로 마더보드에 DIP 장치 8개 또는 9개 형태로 소켓에 배치되어 캐시를 선택적 추가 또는 업그레이드 기능으로 사용할 수 있게 했다.

인텔 386 프로세서의 일부 버전은 16 ~ 256 KiB의 외부 캐시를 지원할 수 있었다.

486 프로세서와 함께 8 KiB 캐시가 CPU 다이에 직접 통합되었다. 이 캐시는 더 느린 온보드 또는 레벨 2 (L2) 캐시와 구별하기 위해 레벨 1 또는 L1 캐시라고 명명되었다. 이 온보드 캐시는 훨씬 더 컸으며, 가장 일반적인 크기는 256 KiB였다. 인텔 485Turbocache 도터카드용 소켓을 포함하는 일부 시스템 보드가 있었는데, 이 카드에는 64 또는 128 Kbyte의 캐시 메모리가 있었다. 온보드 캐시의 인기는 펜티엄 MMX 시대까지 계속되었지만, SDRAM의 도입과 버스 클럭 속도와 CPU 클럭 속도 간의 격차가 커지면서 온보드 캐시가 주 메모리보다 약간만 빨라지면서 쓸모없게 되었다.

x86 마이크로프로세서에서 캐시 구현의 다음 발전은 펜티엄 프로에서 시작되었는데, 이 프로세서는 2차 캐시를 마이크로프로세서와 동일한 패키지에 가져와 마이크로프로세서와 동일한 주파수로 클럭 동작하게 했다.

온보드 캐시는 AMD K6-2 및 AMD K6-III 프로세서 덕분에 오랫동안 인기를 누렸는데, 이들은 이전에 인텔이 온보드 캐시와 함께 사용했던 소켓 7을 여전히 사용했다. K6-III는 256 KiB 온다이 L2 캐시를 포함했고, 온보드 캐시를 L3라는 3단계 캐시로 활용했다(최대 2 MiB의 온보드 캐시를 가진 마더보드가 생산되었다). 소켓 7이 구식이 된 후, 온보드 캐시는 x86 시스템에서 사라졌다.

멀티 코어 프로세서의 도입과 함께 CPU 다이에 L3 캐시가 추가되면서 3단계 캐시가 다시 사용되기 시작했다. 새로운 프로세서 세대에서 총 캐시 크기가 점점 더 커지는 것이 일반적이 되었으며, 최근(2011년 기준)에는 수십 메가바이트의 레벨 3 캐시 크기를 찾는 것이 드물지 않다.

인텔은 하스웰 마이크로아키텍처와 함께 레벨 4 온패키지 캐시를 도입했다. 크리스털웰 하스웰 CPU는 인텔 통합 아이리스 프로 그래픽의 GT3e 변형을 장착하여 사실상 128 MiB의 내장 DRAM(EDRAM)을 동일한 패키지에 탑재하고 있다. 이 L4 캐시는 온다이 GPU와 CPU 간에 동적으로 공유되며, CPU L3 캐시의 희생자 캐시 역할을 한다.

#### ARM 마이크로프로세서에서

애플 M1 CPU는 코어 유형에 따라 각 코어에 128 또는 192 KiB 명령어 L1 캐시를 가지고 있다(지연 시간/싱글 스레드 성능에 중요). 이는 어떤 CPU 유형(노트북뿐만 아니라)에서도 이례적으로 큰 L1 캐시이다. 총 캐시 메모리 크기는 노트북에 비정상적으로 크지 않으며(총량이 처리량에 더 중요), IBM의 메인프레임에서는 훨씬 더 큰 총(예: L3 또는 L4) 크기를 사용할 수 있다.

#### 현재 연구

초기 캐시 설계는 캐시와 RAM의 직접적인 비용과 평균 실행 속도에 전적으로 초점을 맞췄다. 최신 캐시 설계는 에너지 효율성, 내결함성 및 기타 목표도 고려한다.

컴퓨터 설계자를 돕는 여러 도구가 있어 캐시 주기 시간, 에너지 및 면적 간의 트레이드오프를 탐색하는 데 도움을 준다. CACTI 캐시 시뮬레이터와 SimpleScalar 명령어 세트 시뮬레이터는 두 가지 오픈 소스 옵션이다.

### 멀티 포트 캐시

멀티 포트 캐시는 한 번에 두 개 이상의 요청을 처리할 수 있는 캐시이다. 전통적인 캐시에 접근할 때는 일반적으로 단일 메모리 주소를 사용하지만, 멀티 포트 캐시에서는 한 번에 N개의 주소를 요청할 수 있다. 여기서 N은 프로세서와 캐시를 통해 연결된 포트의 수이다. 이점은 파이프라인 프로세서가 파이프라인의 다른 단계에서 메모리에 접근할 수 있다는 것이다. 또 다른 이점은 다른 캐시 수준을 통해 슈퍼스칼라 프로세서의 개념을 허용한다는 것이다.

* 분기 예측
* 캐시
* 캐시 알고리즘
* 캐시 일관성
* 캐시 제어 명령어
* 캐시 계층 구조
* 캐시 배치 정책
* 캐시 프리페칭
* Dinero (위스콘신 대학교의 캐시 시뮬레이터)
* 명령어 장치
* 참조 국부성
* 메모이제이션
* 메모리 계층 구조
* 마이크로 오퍼레이션
* 노-라이트 할당
* 스크래치패드 RAM
* 합 주소 지정 디코더
* 쓰기 버퍼

## 내용주

* Memory part 2: CPU caches—울리히 드레퍼가 lwn.net에 기고한 CPU 캐시에 대한 자세한 설명
* Evaluating Associativity in CPU Caches – 힐과 스미스 (1989) – 용량, 충돌, 강제 분류 소개
* Cache Performance for SPEC CPU2000 Benchmarks – 힐과 칸틴 (2003) – 이 참고 논문은 여러 번 업데이트되었다. 합리적으로 넓은 범위의 벤치마크 및 캐시 조직에 대한 철저하고 명확하게 제시된 시뮬레이션 결과를 포함한다.
* Memory Hierarchy in Cache-Based Systems 보관됨 2009-09-15 - 웨이백 머신 – 루드 반 데어 파스, 2002, 썬 마이크로시스템즈 – CPU 메모리 캐싱 소개 기사
* A Cache Primer – 폴 제누아, P.E., 2004, 프리스케일 반도체, 또 다른 소개 기사
* An 8-way set-associative cache—VHDL로 작성됨
* Understanding CPU caching and performance—아스 테크니카의 존 스토크스 기사
* IBM POWER4 processor review—파벨 다닐로프의 ixbtlabs 기사
* What is Cache Memory and its Types!
* Memory Caching—프린스턴 대학교 강의