C++, CS

[CS] 컴퓨터 메모리 계층 구조와 CPU 캐시 정리

dhlee-dev 2026. 6. 1. 21:28

이전에 vector 와 list의 차이를 정리하면서
vector는 연속된 메모리를 사용하기 때문에 캐시 효율이 좋다는 내용을 언급했었다.

프로세스와 스레드의 차이를 정리할 때도
프로세스 간 전환은 주소 공간이 바뀌기 때문에 캐시 지역성이 떨어지고 캐시 미스가 늘어날 수 있다는 내용도 언급했다.

하지만 당시에는 캐시가 정확히 무엇인지,
왜 메모리 구조나 실행 흐름 전환이 캐시 효율에 영향을 주는지는 자세히 정리하지 않았다.

그래서 이번 글에서는 먼저 CPU 캐시가 무엇인지 캐시 히트와 캐시 미스가 어떤 의미인지 정리해보려고 한다.

캐시는 CPU가 데이터를 더 빠르게 사용하기 위한 저장 공간이지만,
컴퓨터에는 캐시 외에도 레지스터, 메인 메모리, 디스크처럼 역할이 다른 저장 공간들이 존재한다.

따라서 이번에는 CPU 캐시를 중심으로
컴퓨터가 데이터를 저장하고 접근하는 메모리 계층 구조도 함께 정리해보려고 한다.


컴퓨터 메모리 계층 구조

컴퓨터의 메모리 계층 구조는 보통 다음과 같이 정리할 수 있다.

  • 레지스터
  • L1, L2, L3 캐시
  • 메인 메모리
  • 디스크

위로 갈수록 CPU와 가깝고 접근 속도가 빠르다.
하지만 용량이 작고 가격이 비싸다.

반대로 아래로 갈수록 접근 속도는 느리지만,
용량이 크고 상대적으로 저렴하다.

정리하면 다음과 같다.

계층 특징
레지스터 CPU 내부에서 연산에 직접 사용하는 가장 빠른 저장 공간
캐시 CPU와 RAM 사이의 속도 차이를 줄이기 위한 고속 임시 저장 공간
메인 메모리 실행 중인 프로그램의 코드와 데이터가 올라오는 공간
디스크 프로그램과 파일을 장기 저장하는 대용량 저장 공간

레지스터

레지스터는 CPU 내부에 있는 매우 빠른 저장 공간이다.
CPU가 연산을 수행할 때 직접 사용하는 공간이며 메모리 계층 구조에서 가장 빠른 위치에 있다.

하지만 용량은 매우 작다.

따라서 모든 데이터를 레지스터에 저장할 수는 없고,
현재 연산에 필요한 값들을 임시로 저장하는 용도로 사용된다.


캐시

캐시는 CPU가 RAM보다 빠르게 데이터에 접근하기 위해 사용하는 고속 임시 저장 공간이다.
CPU는 RAM에 접근해서 데이터를 읽을 수 있지만 RAM 접근은 CPU 입장에서 상대적으로 느린 동작이다.

만약 CPU가 매번 RAM에서 데이터를 가져와야 한다면
CPU는 데이터를 기다리는 시간이 많아지고, 전체 성능이 떨어질 수 있다.

이 문제를 줄이기 위해 자주 사용할 것 같은 데이터나 명령어를 CPU 가까이에 있는 캐시에 저장해둔다.
그리고 CPU가 데이터를 다시 필요로 할 때 RAM이 아니라 캐시에서 빠르게 가져와 사용할 수 있다.

CPU 캐시는 보통 L1, L2, L3 캐시로 나눌 수 있다.

L1 캐시는 CPU 코어와 가장 가까운 캐시이다.
접근 속도가 가장 빠르지만 용량은 가장 작다.

L2 캐시는 L1보다 조금 느리지만 L1보다 더 큰 용량을 가진 캐시이다.

L1과 L2 캐시는 보통 각 CPU 코어마다 따로 존재한다.

반면 L3 캐시는 L1, L2보다 느리지만 용량이 더 크고,
여러 CPU 코어가 함께 공유하는 캐시로 사용되는 경우가 많다.


메인 메모리

메인 메모리는 보통 RAM(Random Access Memory)을 의미한다.
실행 중인 프로그램의 코드와 데이터가 올라오는 공간이다.

디스크에 저장되어 있던 프로그램은 실행될 때 메모리에 올라오고,
CPU는 메모리에 올라온 코드와 데이터를 읽어가며 프로그램을 실행한다.

RAM은 디스크보다 빠르지만, 전원이 꺼지면 데이터가 사라지는 휘발성 메모리이다.


디스크

디스크는 HDD나 SSD 같은 장기 저장 공간이다.
프로그램, 이미지, 문서, 게임 데이터 같은 파일들은 보통 디스크에 저장된다.

디스크는 용량이 크고 데이터를 오래 보관할 수 있지만 CPU가 직접 연산에 사용하는 공간은 아니다.
디스크에 있는 데이터를 사용하려면 먼저 RAM으로 읽어온 뒤 CPU가 접근해야 한다.


메모리 계층 구조가 필요한 이유

메모리 계층 구조가 필요한 이유는 속도, 용량, 비용의 균형 때문이다.

모든 저장 공간을 레지스터나 캐시처럼 빠르게 만들면 좋겠지만,
그렇게 하면 비용이 너무 커지고 용량도 충분히 확보하기 어렵다.

반대로 모든 데이터를 디스크처럼 큰 저장 공간에만 두면 CPU가 데이터를 가져오는 데 너무 오래 걸린다.
그래서 컴퓨터는 빠르지만 작은 저장 공간과 느리지만 큰 저장 공간을 함께 사용한다.

자주 사용하는 데이터는 CPU 가까이에 두고,
덜 자주 사용하는 데이터는 더 아래 계층에 두는 방식이다.


캐시 히트와 캐시 미스

CPU가 필요한 데이터나 명령어를 찾을 때 그 데이터가 캐시에 있으면 캐시 히트라고 한다.
반대로 캐시에 없으면 캐시 미스라고 한다.

캐시 히트가 발생하면 CPU는 캐시에 있는 데이터를 빠르게 가져와 사용할 수 있다.
하지만 필요한 데이터가 L1 캐시에 없다면 L2, L3 캐시를 확인하고,
그래도 없으면 RAM에서 데이터를 가져와야 한다.

따라서 캐시 히트가 많이 발생할수록 성능에 유리하다.

정리하면 다음과 같다.

구분 의미
캐시 히트 필요한 데이터가 캐시에 있는 경우
캐시 미스 필요한 데이터가 캐시에 없어 더 아래 계층에서 가져와야 하는 경우

캐시의 지역성

캐시가 효과적으로 동작할 수 있는 이유는 지역성 때문이다.

지역성은 프로그램이 특정 데이터나 명령어에 접근할 때,
그 주변 데이터나 최근 접근한 데이터를 다시 사용할 가능성이 높다는 특징이다.

대표적으로 시간 지역성과 공간 지역성이 있다.


시간 지역성

시간 지역성은 최근에 접근한 데이터는 다시 접근할 가능성이 높다는 의미이다.

예를 들어 반복문에서 사용하는 변수는 짧은 시간 안에 여러 번 다시 사용될 수 있다.
이런 데이터가 캐시에 남아 있다면 CPU는 RAM까지 가지 않고 빠르게 접근할 수 있다.


공간 지역성

공간 지역성은 접근한 데이터 근처의 데이터도 곧 접근할 가능성이 높다는 의미이다.

대표적인 예시는 배열이다.

배열은 메모리상에 원소들이 연속적으로 배치되어 있고,
보통 for문을 이용해 앞에서부터 순차적으로 접근하는 경우가 많다.

예를 들어 for문으로 배열을 순회하면
arr[0]에 접근한 뒤 곧바로 arr[1], arr[2]처럼 다음 원소에 접근할 가능성이 높다.


캐시 라인

캐시 라인은 CPU가 RAM에서 데이터를 읽어올 때 한 번에 가져오는 데이터의 단위이다.
CPU는 특정 주소의 데이터가 필요할 때 그 데이터 하나만 가져오지 않고, 일정 크기의 메모리 블록을 함께 가져온다.

이때 함께 가져오는 메모리 블록의 단위를 캐시 라인이라고 하며,
일반적으로 캐시 라인 크기는 64바이트인 경우가 많다.

이렇게 일정 범위의 데이터를 함께 가져오는 이유는
방금 접근한 데이터 근처의 데이터도 곧 사용할 가능성이 높기 때문이다.

즉, 공간 지역성을 활용하기 위한 방식이라고 볼 수 있다.

예를 들어 배열을 순차적으로 순회할 때는 현재 원소 다음에 있는 원소들도 곧 접근할 가능성이 높다.
따라서 캐시 라인 단위로 데이터를 가져오면 이후 접근에서 캐시 히트가 발생할 가능성이 높아진다.


캐시 라인 구조

캐시 라인 엔트리는 보통 다음과 같은 정보로 구성된다.

  • 데이터 블록
  • 태그
  • 플래그 비트

데이터 블록은 RAM에서 가져온 실제 데이터가 저장되는 영역이다.

태그는 해당 캐시 라인의 데이터가 RAM의 어떤 메모리 블록에서 온 것인지 식별하기 위한 값이다.

플래그 비트는 캐시 라인의 상태를 나타내는 정보이다.

예를 들어 해당 데이터가 유효한지 나타내는 Valid bit,
데이터가 수정되어 메모리의 원본과 달라졌는지 나타내는 Dirty bit 등이 있다.

즉, 캐시 라인은 단순히 데이터만 저장하는 것이 아니라,
이 데이터가 어떤 메모리 주소에서 온 것인지와 현재 유효한 데이터인지도 함께 관리한다.


캐시 효율과 자료구조

캐시의 동작 방식을 이해하면 왜 연속된 메모리 구조가 순회 성능에 유리한지 이해할 수 있다.

예를 들어 vector는 원소들이 메모리상에 연속적으로 배치된다.
그래서 반복문으로 순차 접근할 때 한 번 캐시 라인에 올라온 주변 원소들을 이어서 사용할 가능성이 높다.

반면 list는 각 원소가 노드 단위로 따로 할당될 수 있다.
따라서 다음 노드가 메모리상에서 멀리 떨어져 있을 수 있고 순회할 때마다 캐시 미스가 발생할 가능성이 높아질 수 있다.

이 때문에 자료구조를 선택할 때는 시간 복잡도뿐만 아니라 메모리 배치와 캐시 효율도 함께 고려해야 한다.


정리

컴퓨터는 속도, 용량, 비용의 균형을 맞추기 위해 여러 계층의 메모리를 사용한다.

메모리 계층 구조는 다음과 같다.

  • 레지스터
  • 캐시
  • 메인 메모리
  • 디스크

레지스터와 캐시는 CPU와 가까워 빠르지만 용량이 작고,
RAM과 디스크는 상대적으로 느리지만 더 많은 데이터를 저장할 수 있다.

CPU 캐시는 RAM 접근 비용을 줄이기 위해 사용된다.

CPU가 필요한 데이터가 캐시에 있으면 캐시 히트, 없으면 캐시 미스가 발생한다.

캐시는 시간 지역성과 공간 지역성 덕분에 효과적으로 동작할 수 있다.

캐시 라인은 CPU가 메모리에서 데이터를 가져올 때 사용하는 단위이며,
주변 데이터까지 함께 가져와 이후 접근을 빠르게 만들 수 있다.


마무리

이전 글들에서 vector는 캐시 효율이 좋다는 식의 내용을 언급한 적이 있었다.

당시에는 캐시 효율이라는 말을 어느 정도는 알고 있다고 생각했지만,
캐시가 실제로 어떤 방식으로 동작하는지까지 정확히 이해하고 있지는 않았다.

이번에 CPU 캐시를 정리하면서 캐시 히트와 캐시 미스가 무엇인지,
CPU가 왜 캐시 라인 단위로 주변 데이터까지 함께 가져오는지 알 수 있었다.

또한 캐시뿐만 아니라 레지스터, L1 / L2 / L3 캐시, 메인 메모리, 디스크처럼
컴퓨터가 여러 계층의 저장 공간을 사용한다는 것도 함께 정리할 수 있었다.

결국 더 효율적인 코드를 작성하려면 단순히 문법이나 시간 복잡도만 보는 것이 아니라,
데이터가 메모리에 어떻게 배치되고 CPU가 그 데이터를 어떻게 가져오는지도 이해해야 한다고 느꼈다.