캐시 메모리의 개념과 종류, 역할
실제 메모리와 CPU 사이에서 빠르게 전달을 위해 미리 데이터들을 저장해주는 좀 더 빠른 메모리이다.
일반적으로 CPU 칩에 직접 통합되거나 별도의 BUS 상호 연결이 있는 별도의 칩에 배치되기 때문에 CPU 메모리라고도 한다.
따라서 프로세서에 대한 접근성이 더 좋고, 프로세서와 물리적으로 가깝기 때문에 효율성을 높일 수 있다.
프로세서에 가깝기 위해서 메인 메모리보다 훨씬 작다. 결과적으로 저장 공간이 적다.
대신 캐시 메모리는 RAM보다 10~100배 빠르게 작동한다.
종류
일반적인 세 가지 캐시 수준이 있다.
- L1
- L2
- L3
L1: Lightning-Fast Access
매우 빠르지만 상대적으로 작으며 일반적으로 프로세서 칩에 CPU 캐시로 내장된다.
자주 사용되는 명령어와 데이터를 저장하여 CPU가 빠르게 액세스할 수 있도록 하는 것이다. Central Processing Unit
CPU 가 자주 액세스하는 명령어와 데이터의 숨겨진 캐시라고 생각하면 된다.
L2: Bridging the Gap
L1보다 용량이 더 큰 경우가 많다.
CPU에 내장될 수도 있고 별도의 칩이나 보조 프로세서에 있을 수도 있고 캐시와 CPU를 연결하는 고속 대체 시스템 버스가 있을 수도 있다.
이렇게 하면 메인 시스템 버스의 트래픽으로 인해 속도가 느려지지 않는다.
자주 요청되는 데이터와 명령어를 위한 더 많은 저장 공간을 제공하여 CPU가 메인 메모리에 액세스해야 하는 필요성을 최소화한다.
일부 멀티코어 아키텍처에서는 L2 캐시를 CPU 코어 간에 공유할 수 있다.
L3: The Shared Resource
L1 및 L2의 성능을 향상시키기 위해 개발된 특수 메모리이다.
L1과 L2는 L3보다 훨씬 빠를 수 있지만, 일반적으로 L3는 DRAM의 2배 속도이다.
멀티 코어 프로세서에서 L3 캐시는 모든 CPU 코어의 공유 리소스이다.
일반적으로 사용되는 데이터와 명령어를 위한 공유 캐시 공간을 생성하여 코어 간에 데이터를 효율적으로 공유할 수 있도록 한다.
이는 멀티 스레드 및 멀티 코어 프로그램에서 CPU 성능을 높게 유지하는 데 매우 중요하다.
Cache memory
CPU는 데이터를 처리할 때 캐시 메모리를 먼저 살펴보고 캐시 메모리에서 데이터를 찾으면 시간이 많이 걸리는 데이터 읽기를 수행할 필요가 없다. 캐시 메모리는 데이터 Locality(지역성)의 원리를 사용한다.
또한, CPU가 데이터를 요청했을 때, 캐시 메모리가 해당 데이터를 가지고 있다면 이를 Cache Hit
라 부르고, 데이터가 없어 DRAM에서 가져와야 한다면 Cache Miss
라고 부른다. 캐시 미스 발생 시, 처리 방법은 캐시 정책에 따라 다르며, 데이터를 읽어 오는 시점으로 사용하기도 한다.
근래에는 아래 그림과 같은 형태이다.
Locality(지역성)의 원리
- 시간 지역성
- 공간 지역성
시간 지역성은 어떤 메모리 주소에 접근했을 때, 잠시 후에 이와 동일한 주소에 접근할 확률이 높으면 시간 지역성이 좋다고 표현한다.
반복문에서 사용하는 조건 변수처럼 한 번 참조된 데이터를 또 참조하게 될 가능성을 의미한다.
공간 지역성은 어떤 메모리 주소에 접근했을 때, 잠시 후 그 근처의 메모리 주소에 접근할 확률이 높으면 공간지역성이 좋다고 표현합니다.
배열에 있는 데이터를 연속으로 접근할 때 근처에 있는 데이터를 잠시 후 사용될 가능성을 의미한다.
이름 그대로 시간과 공간
을 기준으로 다음번 메모리 접근 때 접근할 가능성이 높은 메모리 주소를 지역성이 좋다라고 표현한다.
[번외] 참조의 지역성의 효율성
가장 유명한 예시로 배열 곱셈이 있다.
for i in 0...n {
for j in 0...m {
for k in 0...p {
C[i][j] = C[i][j] + A[i][k] * B[k][j]
}
}
}
배열의 마지막 차원에 원소를 연속적으로 정렬하는 언어에서는 루프 순서인 j와 k의 위치를 바꾸는 것만으로도 엄청난 속도 증가한다.
특히, 원소가 10만 개가 넘거나 L1, L2 캐시가 감당하지 못할 만큼 큰 배열의 경우 엄청난 효율을 자랑한다.
첫 번째 코드는 A[i][k] 배열이 캐시에 있다. k가 마지막 차원에서 연속적으로 증가하기 때문이다.
하지만 B[k][j]는 첫 번째 차원에서 k가 증가하므로 캐시 미스가 나게 된다.
// Cache Hit를 올리는 구조의 반복문
for i in 0...n {
for k in 0...p {
for j in 0...m {
C[i][j] = C[i][j] + A[i][k] * B[k][j]
}
}
}