목표 : 저장 장치 계층 구조 , 캐시 메모리 학습
저장 장치 계층 구조
저장 장치에서, "빠르다" 와 "용량이 크다"는 공존하기 힘든 특성이다. 따라서 저장 장치는일반적으로 다음 명제를 따른다.
- CPU와 가까운 저장 장치는 빠르고, 멀리 있는 저장 장치는 느리다.
- 속도가 빠른 저장 장치는 저장 용량이 작고, 가격이 비싸다.
예를 들어,
- CPU에 내장된 **레지스터(register)**는 매우 빠르지만 용량이 극히 작고 가격이 높다.
- **RAM(주기억장치)**는 레지스터보다는 느리지만 용량이 크고 가격이 저렴하다.
- USB, SSD, HDD 등의 저장장치는 RAM보다도 더 느리지만, 훨씬 큰 용량을 제공한다.
이렇게 저장 장치마다 특성이 다르므로, 한 가지의 저장 장치를 이용하는 것이 아니라, 여러 장치들을 조합해 사용한다.
이렇게 사용하는 모든 저장 장치들을 'CPU에 얼마나 가까운가'를 기준으로 계층적으로 나타낸 것을
저장 장치 계층 구조(Memory hierarchy)라고 한다.
캐시 메모리
CPU가 메모리에 접근하는 속도는 레지스터에 접근하는 속도보다 느리다.
그럼에도 프로그램을 실행하기 위해서 메모리에 빈번하게 접근해야만 한다. CPU 연산 속도가 아무리 빨라도
메모리 접근 속도가 이를 따라가지 못한다면 CPU의 성능을 온전하게 사용할 수 없다.
그래서 캐시 메모리(cache memory)가 등장했다.
- 캐시 메모리는 CPU와 메모리 사이에 위치한 고속 저장 장치로서, 주로 SRAM 기반으로 구성되어 있다.
- CPU가 자주 사용할 것으로 예상되는 데이터를 임시로 저장해두어, 메모리에 직접 접근하는 횟수를 줄이고 속도를 향상시킨다.
컴퓨터 내부에는 여러 개의 캐시 메모리가 있고, 이 캐시 메모리들은 CPU(코어)와 가까운 순서대로 계층을 구성한다.
캐시 메모리도 여러 단계로 나뉘며, CPU와의 거리(가깝고 빠름)에 따라 다음과 같이 분류된다:
- L1 캐시: 코어 내부에 있으며, 속도는 가장 빠르지만 용량이 작고 고가.
- L2 캐시: L1보다는 느리지만 용량은 더 크며, 코어 내부 또는 외부에 존재. (일반적으로 내부에 존재)
- L3 캐시: 여러 CPU 코어가 공유하며, L1/L2보다 느리고 용량이 큼.
위에서 살펴본 순서처럼, 가까운 L1이 가장 빠르고 , 가장 용량이 작고 비싸다.
CPU는 메모리 내에 데이터가 필요하다고 판단하면 L1 캐시에 해당 데이터가 있는지 알아보고, 없으면 L2, L3에서 찾는다.
일반적으로 멀티 코어 프로세서에서 L1, L2 캐시는 코어마다 고유한 메모리로 할당되고, L3는 여러 코어가 공유한다.
코어와 가장 가까운 L1 캐시는 조금이라도 접근 속도를 빠르게 만들기 위해 명령어만을 저장하는 L1I 캐시와
데이터만을 저장하는 L1D 캐시가 있으며 이를 분리형 캐시(Split cache)라고 부른다.
책에서 다루지 않는 저장장치(클라우드 저장 장치 등)도 얼마든지 계층 구조에 추가될 수 있으나,
중요한 점은 상위 계층과 하위 계층을 이루고 있는 저장 장치의 특성을 이해하는 것이다.
참조 지역성의 원리
메모리의 모든 내용을 캐시 메모리에 저장할 수는 없다. 따라서 메모리가 보조 기억 장치의 일부를 복사하여 저장하는 것처럼
캐시 메모리도 메모리의 일부를 복사하여 저장한다. 중요한 것은 "어떤 것을 복사하여 저장"해야 하는지 선택하는 일이다.
캐시 메모리는 CPU가 사용할 법한 대상을 예측하여 저장한다. 이 때, 자주 사용될 것으로 예측한 데이터가 실제로 들어맞아 캐시 메모리 내 데이터가 CPU에서 활용될 경우를 캐시 히트(cache hit)라고 한다.
반대로 예측이 틀려 메모리에서 필요한 데이터를 직접 가져와야 하는 경우를 캐시 미스(cache miss)라고 한다.
캐시 미스가 발생한다면, 필요한 데이터를 메모리에서 직접 가져와야 하기 때문에 캐시 메모리의 이점을 활용할 수 없다.
따라서 캐시가 히트되는 비율인 캐시 적중률(cache hit ratio)을 높이는 것이 중요하다. ( 캐시 히트 / 캐시 히트 수 + 캐시 미스 수)
일반적으로 우리가 사용하는 컴퓨터의 캐시 적중률은 대략 85~95% 이상이다.
캐시 적중률을 높이기 위해서, 캐시 메모리는 참조 지역성의 원리(locality of reference, principle of locality)의 원리에 따라
메모리로부터 가져올 데이터를 결정한다. 이는 CPU가 메모리에 접근할 때의 주된 경향을 바탕으로 만들어진 원리다.
- CPU가 최근 접근했던 메모리 공간에 다시 접근하려는 경향
- CPU가 접근한 메모리 공간 근처를 접근하려는 경향
CPU가 최근 접근했던 메모리 공간에 다시 접근하려는 경향
보통 프로그래밍 언어를 배울 때 '변수'라는 것을 배운다. 변수에 값을 저장하고 나면 우리는 언제든지 변수에 접근하여 변수에 저장된 값을 활용할 수 있다. 이는 CPU가 변수가 저장된 메모리 공간을 참조할 수 있다는 말과 똑같다. 일반적으로 변수에 저장한 값은 프로그램이 실행되면서 여러번 실행되기 때문에 접근했던 메모리 공간에 여러 번 접근하는 경향이 있다.
이를 시간 지역성(temproral locality)라고 한다.
CPU가 접근한 메모리 공간 근처를 접근하려는 경향
CPU가 실행하려는 프로그램은 보통 관련 데이터들끼리 한데 모여 있다. 또한 하나의 프로그램 내에서도 관련이 있는 데이터들은 모여서 저장된다. 그래서 같은 기능을 실행하려고 할 때 기능이 모여 있는 공간 근처를 집중적으로 접근하게 된다.
이를 공간 지역성(spatial locality)라고 한다.
이 참조 지역성의 원리를 통해 CPU가 사용할만한 데이터를 예측한다.
질문 : 어떤 데이터가 정확히 어떤 캐시에 있는지 확인하는 방법
캐시는 데이터를 '블럭 단위'로 저장하고, '인덱스 + 태그'로 위치와 진위를 판단하는 구조를 만들어 두었다.
예를 들어 예시 주소: 0x04C (이진수로 0000 0000 0100 1100)일 때
주소를 다음과 같이 나눈다.
Offset | 4비트 (16바이트 = 2⁴) | 1100 | 블록 내 위치 (0~15) |
Index | 2비트 (4블록 = 2²) | 01 | 캐시의 몇 번째 블록에 저장할지 |
Tag | 나머지 (32 - 6 = 26비트) | 000... | 이 블록이 어떤 메모리 주소에서 온 것인지 구별 |
CPU가 0x04C라는 메모리 주소를 요청한다면
1. Index = 01이니 캐시의 1번 블록을 확인한다.
2. 그 블록에 저장된 tag를 확인한다.
3. 요청한 주소의 Tag와 같다면 Cache hit 아니면 Cache Miss
질문 : 그럼 같은 Index의 데이터가 메모리에 많다면, 성능이 저하되지 않을까 ?
메모리 주소들이 같은 캐시 블록(같은 인덱스)에 자꾸 매핑되면 충돌이 생기고, 계속 교체해야 하니 비효율적이다. 그럼 실제 메모리는 그런 일이 잘 안 생기게 짜여 있을까?
같은 인덱스를 공유하는 주소가 자주 발생하면 캐시 충돌(Cache Conflict)가 발생한다.
예를 들어, 캐시가 이렇게 되어 있다면:
- 총 4개의 블록 → Index는 0, 1, 2, 3
- 주소 0x100, 0x110, 0x120, 0x130은 모두 Index=0에 매핑됨
이 주소들을 번갈아가며 접근할 때마다 계속해서 블럭 0이 덮어쓰게 되고 캐시 미스가 반복해 성능이 저하된다.
따라서 이러한 문제를 해결하기 위해 컴파일러나 운영체제(OS)는 가능한 지역성을 고려해서 메모리를 배치하려 한다.
예를 들어 배열 , 함수, 루프 등이 연속된 주소를 갖도록 만들어서 충돌 가능성을 줄인다. (여전히 문제가 생길 수 있다)
그래서 캐시 매핑 방식으로 해결하려고 한다. 다음은 세 가지 캐시 매핑 방식이다.
'개념공부 > 컴퓨터구조와 운영체제' 카테고리의 다른 글
07장 - 2 : RAID의 정의와 종류 (0) | 2025.04.24 |
---|---|
07장 - 1 다양한 보조기억장치 (1) | 2025.04.23 |
06장 - 2 : 메모리의 주소 공간 (0) | 2025.04.14 |
06장 - 1 : RAM (0) | 2025.04.11 |
05장 -3 : CISC와 RISC (0) | 2025.04.11 |