7강 / 20강

메모리 계층 — 가까울수록 작고 비싸다

레지스터에서 서울-런던까지, 기다림의 지도

메모리 계층 — 가까울수록 작고 비싸다
빠른 것은 작고 비쌉니다. 그래서 층층이 쌓습니다.

CPU가 값 하나를 가져오는 데 걸리는 시간은 그 값이 어디 있느냐에 따라 어마어마하게 달라집니다. 얼마나 달라지는지 감이 잘 안 오죠?

그래서 1나노초를 1초로 늘려 사람의 시간으로 바꿔 보겠습니다.

기다림의 지도 — 나노초를 사람 시간으로 늘려 봅니다. 막대를 눌러 보세요.
불러오는 중…
나노초를 초로 늘리면 감이 옵니다.
Python 브라우저에서 실행

왜 그냥 전부 빠른 걸로 만들지 않을까

답은 셋입니다 — 돈, 크기, 물리 법칙.

계층크기1GB당 값(대략)왜 이 크기인가
레지스터수백 바이트—ALU 옆에 붙어야 해서
L1 캐시48KB/코어수천만 원1클럭 안에 닿아야 해서
L3 캐시12MB수백만 원칩 면적을 차지해서
DRAM16GB약 5,000원칩 밖이라 신호가 멀다
NVMe SSD512GB약 200원전원이 꺼져도 남아야 해서

L1을 16GB로 만들면? 칩이 자동차만 해지고, 신호가 한쪽 끝에서 다른 끝까지 가는 데 클럭 수백 개가 걸려서 결국 느려집니다. 크면 느릴 수밖에 없어요.

그럼 왜 이 계층이 실제로 잘 먹힐까 — 지역성

층층이 쌓아 놓고 "자주 쓰는 건 위층에" 두는 전략이 통하는 이유는 프로그램이 메모리를 제멋대로 쓰지 않기 때문입니다.

🕐
시간 지역성
방금 쓴 건 곧 또 쓴다
반복문의 변수 i
📏
공간 지역성
쓴 것 옆을 또 쓴다
배열을 순서대로 훑기

이 두 습관 덕분에, 아주 작은 캐시로도 95% 이상을 잡아낼 수 있습니다.

히트율 9%p 하락 = 4배 느려짐.
Python 브라우저에서 실행

내 서버의 계층을 확인해 봅시다

이 서버의 캐시 크기와 캐시 라인 크기입니다.
bash 브라우저에서 실행

coherency_line_size가 64죠. 이게 캐시 라인입니다 — CPU가 메모리에서 뭔가를 가져올 때 항상 64바이트씩 통째로 가져온다는 뜻이에요. 1바이트만 필요해도 64바이트를 들고 옵니다.

왜 그럴까요? 공간 지역성 때문입니다. 어차피 옆 것도 곧 쓸 테니까. 다음 강에서 이 64바이트가 성능을 어떻게 가르는지 직접 재 봅니다.

-T 는 디스크가 아니라 캐시를 잰 값입니다. 차이를 보세요.
bash 브라우저에서 실행
🤔 확인 문제
서버가 스왑을 쓰기 시작하면 응답이 수십 배 느려집니다. 메모리 계층으로 설명하면?
🤔 확인 문제
캐시가 작은데도 잘 먹히는 이유는?