LODY/정리

컴퓨터 구조 / 메모리 계층과 캐시

메모리 계층과 캐시

🟣 빨라진 프로세서가 메모리를 기다린다

앞 장에서 파이프라인은 매 사이클 명령어를 뽑아낼 만큼 프로세서를 밀어 올렸다. 그런데 그 명령어의 상당수가 메모리에서 값을 읽거나 쓴다. 문제는 메모리가 프로세서만큼 빨라지지 못했다는 데 있다. 프로세서 속도는 오랜 세월 가파르게 올랐지만 DRAM 접근 속도는 훨씬 완만하게 올랐고, 그 격차가 벌어질수록 프로세서는 데이터를 기다리며 놀게 됐다.

숫자로 보면 심각하다. 레지스터 접근이 한 사이클이라면, 주 기억장치(DRAM) 접근은 수십에서 수백 사이클이 걸린다. lw 한 번에 프로세서가 백 사이클을 논다면, 애써 만든 파이프라인이 무색해진다. 이 장은 그 격차를 메우는 장치, 곧 메모리 계층과 캐시가 왜 필요했고 어떻게 동작하는지를 본다.


🟣 빠르고 작거나, 느리고 크거나

이상적인 메모리는 무한히 크고 무한히 빠르고 값도 싸야 한다. 현실에서 이 셋은 동시에 성립하지 않는다. 빠른 저장 장치는 비싸고 작으며, 싸고 큰 저장 장치는 느리다. 그래서 하나로 해결하는 대신 여러 종류를 계층으로 쌓는다.

위로 갈수록 빠르고 작고 비싸며, 아래로 갈수록 느리고 크고 싸다. 맨 위 레지스터에서 시작해 캐시(보통 L1, L2, L3로 나뉜다), 주 기억장치인 DRAM, 그 아래 디스크로 내려간다. 핵심 아이디어는 이것이다. 자주 쓰는 데이터를 위쪽 빠른 계층에 두고, 나머지는 아래에 두어, 대부분의 접근이 위쪽에서 끝나게 만든다. 그러면 평균 접근 시간이 위쪽 계층에 가까워진다.

레지스터 (1 사이클, 수백 바이트)L1/L2/L3 캐시 (수~수십 사이클, KB~MB)주 기억장치 DRAM (수십~수백 사이클, GB)디스크/SSD (수만 사이클 이상, TB)넘치면 아래로

이 계층이 성립하려면 전제가 하나 필요하다. "자주 쓰는 데이터"가 실제로 존재하고, 그것을 예측할 수 있어야 한다. 그 전제를 뒷받침하는 것이 지역성이다.


🟣 지역성: 캐시가 통하는 이유

프로그램의 메모리 접근은 아무렇게나 흩어지지 않는다. 뚜렷한 두 가지 쏠림이 있고, 이것을 지역성이라 부른다.

시간 지역성은 방금 접근한 데이터를 곧 다시 접근하는 경향이다. 반복문의 카운터 변수는 매 반복마다 읽히고, 자주 부르는 함수의 코드는 계속 실행된다. 공간 지역성은 방금 접근한 곳 근처를 이어서 접근하는 경향이다. 배열을 순서대로 훑거나, 명령어를 주소 순으로 실행하는 경우다.

캐시는 이 두 쏠림을 그대로 이용한다. 시간 지역성에 기대어 한 번 가져온 데이터를 버리지 않고 캐시에 남겨 두고, 공간 지역성에 기대어 한 바이트가 아니라 그 주변까지 한 덩어리(블록 또는 라인)로 가져온다. 배열의 한 원소를 읽을 때 옆 원소들까지 통째로 캐시에 올려 두면, 다음 원소들은 이미 캐시에 있어 빠르게 읽힌다. 지역성이 없다면 캐시는 무용지물이고, 지역성이 있기에 작은 캐시가 큰 효과를 낸다.


🟣 주소를 셋으로 자른다

캐시는 데이터를 블록 단위로 담는다. 어떤 주소의 데이터를 찾을 때, 캐시는 그 주소를 세 조각으로 잘라 읽는다. 어느 칸에 있을지(인덱스), 그 칸에 있는 것이 정말 내가 찾는 블록인지(태그), 블록 안 어디인지(오프셋)를 각각 다른 비트가 담당한다.

필드태그인덱스블록 오프셋
역할이 칸의 블록이 맞는지 확인캐시의 몇 번 칸인지블록 안 몇 번째 바이트인지

접근이 들어오면 인덱스로 칸을 찾아가고, 그 칸에 저장된 태그와 주소의 태그를 비교한다. 태그가 같으면 원하는 블록이 이미 캐시에 있는 것이니 캐시 히트이고, 오프셋으로 정확한 바이트를 꺼낸다. 태그가 다르거나 칸이 비었으면 캐시 미스이고, 아래 계층에서 블록을 통째로 가져와 그 칸에 채운 뒤 넘긴다. 캐시가 빠른 이유는 이 조회가 몇 사이클 안에 끝나기 때문이다.


🟣 어느 칸에 넣을 것인가: 사상 방식

블록을 캐시의 어느 칸에 넣느냐에 따라 세 가지 사상 방식이 있다. 여기에도 성능과 비용의 타협이 있다.

직접 사상은 한 블록이 들어갈 칸이 딱 하나로 정해진다. 조회가 단순하고 빠르지만, 서로 다른 두 블록이 같은 칸에 배정되면 번갈아 쓸 때마다 상대를 쫓아내며 미스가 반복된다. 완전 연관은 반대로 블록을 어느 칸에나 넣을 수 있다. 쫓아냄이 줄지만, 찾을 때 모든 칸의 태그를 다 비교해야 해서 회로가 비싸다. 집합 연관은 그 사이의 절충이다. 칸 몇 개를 한 묶음으로 두고, 블록은 정해진 묶음 안 어느 칸에나 들어간다. 조회 비용과 충돌을 함께 낮춘 방식이라 실제 프로세서 캐시가 대부분 이쪽을 쓴다.

블록 주소직접 사상정해진 칸 1개집합 연관정해진 묶음 안여러 칸 중 하나완전 연관아무 칸이나단순·충돌 잦음절충 (실제 다수)유연·비쌈

🟣 미스는 왜 나는가: 세 가지 원인

캐시 미스를 원인별로 나누면 어디를 손봐야 할지 보인다. 세 종류로 갈린다.

강제 미스는 그 블록을 처음 접근할 때 나는 미스다. 캐시에 아직 한 번도 올라온 적이 없으니 피할 수 없다. 블록을 크게 잡아 한 번에 많이 끌어오면 뒤이은 접근의 강제 미스를 줄일 수 있다. 용량 미스는 프로그램이 쓰는 데이터가 캐시 크기보다 커서, 쫓겨났던 블록을 다시 불러오며 나는 미스다. 캐시를 키우는 것 말고는 근본 대책이 없다. 충돌 미스는 캐시에 자리가 있는데도 사상 방식 탓에 같은 칸으로 몰려 서로를 쫓아내며 나는 미스다. 연관도를 높이면(집합 연관, 완전 연관) 줄어든다.

쓰기 정책도 짧게 짚는다. 캐시에 쓴 값을 곧바로 아래 계층에도 반영하면(write-through) 일관성은 간단하지만 쓰기가 잦으면 느리고, 캐시에만 써 두고 쫓겨날 때 한꺼번에 반영하면(write-back) 빠른 대신 관리가 복잡하다. 여기서도 단순함과 성능이 맞바꿔진다는 같은 구도가 반복된다.


🟣 지역성이 실제 성능을 가른다

공부가 여기서 실무의 성능 감각으로 이어졌다. 캐시는 하드웨어가 알아서 관리하니 프로그래머가 직접 건드릴 일은 없어 보이지만, 코드가 메모리를 어떤 순서로 접근하느냐가 지역성을 좌우하고, 그것이 곧 캐시 히트율을 좌우한다.

가장 흔한 예가 이차원 배열 순회다. 배열은 메모리에 한 줄씩 이어져 저장되는데(행 우선), 바깥 반복을 행, 안쪽 반복을 열로 돌면 이어진 주소를 차례로 밟아 공간 지역성이 산다. 순서를 뒤집어 열을 먼저 돌면 매번 멀리 떨어진 주소로 건너뛰어, 가져온 블록의 나머지를 못 쓰고 버리며 미스가 폭증한다. 알고리즘의 계산량은 똑같은데 접근 순서만 바꿔도 실측 속도가 몇 배씩 갈린다. 구조체의 필드를 자주 함께 쓰는 것끼리 모아 두는 것도 같은 이유다.

이 감각은 앱 개발에서도 그대로 통했다. 리스트를 빠르게 스크롤할 때 셀 데이터를 미리 이어진 형태로 준비해 두면 접근이 매끄럽고, 여기저기 흩어진 객체를 매번 따라다니면 느려진다. CS 이론에서 배운 지역성이 실제 사용자가 느끼는 부드러움과 만나는 지점이었다. 캐시를 안다는 것은 캐시 회로를 외우는 게 아니라, 내 코드의 접근 패턴이 그 회로에 어떻게 걸리는지를 아는 것이었다.


🟣 정리

  • 프로세서는 빨라졌지만 DRAM은 수십에서 수백 사이클로 느려, 그 격차를 메우려고 메모리 계층을 쌓는다.
  • 빠르고 작은 계층 위에 자주 쓰는 데이터를 두어 평균 접근 시간을 위쪽에 가깝게 만든다. 이것이 성립하는 근거가 지역성이다.
  • 캐시는 주소를 태그·인덱스·오프셋으로 잘라 조회하고, 데이터를 블록 단위로 담아 공간 지역성을 활용한다.
  • 사상 방식(직접·집합 연관·완전 연관)과 미스 종류(강제·용량·충돌)는 모두 성능과 비용의 타협 위에 있다.
  • 코드의 메모리 접근 순서가 지역성을 좌우하고, 그것이 실측 성능을 몇 배씩 가른다.

면접에서 캐시를 물으면 히트·미스의 정의에서 멈추지 말고, 배열 순회 순서 같은 구체적 코드가 지역성으로 어떻게 성능을 가르는지까지 내려가야 한다. 캐시 지식을 접근 패턴 최적화 경험과 이어 말할 수 있으면, 이론과 실무를 함께 갖춘 신호가 된다.

여기까지가 컴퓨터 구조의 한 바퀴였다. 명령어 집합이라는 약속에서 출발해, 그 명령어를 실행하는 datapath를 세우고, 처리량을 위해 파이프라인으로 겹쳐 흘리고, 그 속도를 메모리가 못 따라오는 문제를 캐시로 메웠다. 소프트웨어와 하드웨어가 하나의 흐름으로 맞물려 돈다는 처음의 문장을, 각 계층을 직접 따라가며 확인한 여정이었다. 학부에서 얇게 스친 교재를, 라즈베리파이를 옆에 두고 실물과 맞춰 가며 한 번 더 깊이 판 기록으로 남긴다.