LabHub

블로그

컴퓨터 아키텍처의 현대 — CPU 파이프라인·Out-of-Order·캐시·브랜치 예측·Meltdown·Apple Silicon·ARM·RISC-V·SIMD·GPU 심층 가이드 (2025)

한국어English日本語

왜 2025년의 백엔드 엔지니어가 CPU 내부를 알아야 하는가

Rust를 썼는데 왜 C보다 느릴 때가 있는가. HashMap을 쓰는데 왜 Vec<(K,V)> 선형 탐색이 더 빠른 순간이 있는가. if 하나가 왜 10배 느려지는가. 왜 M1이 같은 세대 Intel을 이겼는가. 정답은 모두 CPU 내부에서 일어나는 일을 이해하면 자명하다. 소프트웨어는 결국 하드웨어 위에서 돈다. CPU는 우리가 a + b라고 쓴 코드를 그 순서대로 실행하지 않는다. 파이프라인, 캐시, 브랜치 예측자, 메모리 컨트롤러가 보이지 않게 개입한다. 이 글은 그 내부를 연다.

2018년 Meltdown/Spectre 이후 "CPU는 더 이상 블랙박스가 아니다"가 업계 상식이 됐다. Apple Silicon M1(2020)은 "RISC ARM이 x86을 정확히 이길 수 있음"을 증명했고, AWS Graviton4·NVIDIA Grace·Ampere Altra는 클라우드 비용 30% 절감을 현실로 만들었다. RISC-V는 Western Digital·SiFive·Tenstorrent·Meta가 실리콘을 굽는 단계다. GPU는 H100/H200을 넘어 B100/B200 Blackwell(2024)·GB300(2025)이 LLM 경제를 지배한다. 모든 소프트웨어 엔지니어가 이 흐름을 피할 방법이 이제는 없다.

이 글은 앞서 쓴 Rust 심층 가이드와 연결된다. Rust가 zero-cost abstraction을 선언할 수 있는 이유는 결국 CPU 친화적 코드로 컴파일되기 때문이고, 그 "CPU 친화"의 정체를 이 글에서 해부한다.

1부. 트랜지스터에서 명령어까지 — 당신의 if 문이 진짜로 하는 일

1.1 폰 노이만에서 현대 CPU까지의 30초

1945년 폰 노이만이 제안한 구조는 지금도 논리적으로 바뀌지 않았다. 메모리에 코드와 데이터가 같이 있고, CPU가 순차적으로 읽어 실행한다. 하지만 물리적으로는 상전벽해가 일어났다.

한 칩 안에 200억 개 넘는 트랜지스터가 들어가지만, 우리가 짜는 코드는 여전히 a + b다. 그 간극을 메우는 게 현대 CPU의 설계다.

1.2 명령어가 실행되는 5단계(사실은 20단계)

교과서가 말하는 RISC 파이프라인 5단계.

  1. Fetch — 메모리에서 명령어 읽기
  2. Decode — 무엇을 하라는 건지 해석
  3. Execute — 실제 연산
  4. Memory Access — 필요하면 메모리 read/write
  5. Write Back — 결과를 레지스터에 저장

현대 x86 (Golden Cove, Zen 4)은 이것이 14~20 단계로 더 잘게 쪼개져 있다. 그래야 각 단계가 더 빨리 끝나고 클럭을 더 높일 수 있다. 단, 파이프라인이 길어질수록 브랜치 예측 실패 비용이 커진다.

1.3 슈퍼스칼라 — 한 사이클에 4~8개 명령

단일 명령 파이프라인은 1990년대에 끝났다. 지금은 한 클럭 사이클에 여러 명령을 동시에 issue한다.

이게 왜 중요한가? 당신이 짠 C/Rust 코드의 IPC(Instructions Per Cycle)가 3~4에 달하면, CPU가 병렬로 여러 연산을 굴리고 있다는 뜻이다. 반대로 IPC가 0.5라면, 뭔가 파이프라인을 죽이고 있다(브랜치 미스, 캐시 미스, 의존성 체인).

2부. Out-of-Order 실행 — CPU는 당신 코드를 재정렬한다

2.1 왜 재정렬하는가

int a = load_from_memory(&x);  // 100 사이클 걸리는 미스
int b = 2 + 2;                  // 1 사이클

In-order CPU는 첫째 줄이 끝날 때까지 b를 시작 못한다. Out-of-Order CPU는 b를 먼저 실행하고 a가 도착하면 그제서야 합친다. 명령어 사이에 의존성이 없으면 순서 상관없이 실행한다.

2.2 ROB, RS, Register Renaming

"코드상의 RAX가 실제로는 192개 물리 레지스터 중 하나"로 매핑되기 때문에, false dependency가 제거된다. Apple M3의 ROB는 약 700 entries, Zen 5는 약 480. 이 숫자가 클수록 더 멀리 보고 재정렬할 수 있다.

2.3 Speculative Execution — 미래를 먼저 살아본다

분기 예측 → 둘 중 하나를 가정하고 실행 → 맞으면 이익, 틀리면 롤백. 이걸 잘못 설계한 결과가 2018년 Spectre/Meltdown이다(4부에서 다룸).

3부. 캐시 계층 — 왜 배열이 linked list를 이기는가

3.1 메모리 계층의 현실

2025년 기준 대략적 수치(x86 P-core, 빠를수록 위).

계층용량레이턴시처리량
레지스터~4000 사이클per-op
L1d48~80KB4~5 사이클3~4 load/cycle
L22~3MB12~15 사이클1 load/cycle
L332~96MB40~50 사이클shared
DRAM32~512GB200~300 사이클50~100 GB/s
NVMeTB급10~100μs7~14 GB/s
네트워크100μs~10~100 Gb/s

레지스터와 DRAM 사이에 약 100배 차이가 있다. 캐시는 이 간극을 메우는 장치다.

3.2 Cache Line — 캐시의 최소 단위는 64바이트

CPU는 1바이트만 읽어도 64바이트(Apple Silicon은 128바이트)를 통째로 가져온다. 이것이 "배열이 linked list를 이기는 가장 큰 이유".

한 요소 100 사이클 vs 5 사이클, 즉 20배 차이.

3.3 Prefetch — CPU가 미래를 준비한다

하드웨어 프리페처는 접근 패턴을 감지해서 미리 L1/L2로 당겨놓는다. 선형 스트라이드(a[0], a[1], a[2]...)는 완벽히 감지되고, 복잡한 포인터 체이싱은 실패한다. 소프트웨어적으로는 __builtin_prefetch(ptr) (GCC/Clang)로 힌트를 줄 수 있다.

3.4 False Sharing — 64바이트 안의 지옥

두 스레드가 같은 캐시 라인의 서로 다른 변수를 쓰면, 하드웨어 코히런시 프로토콜(MESI)이 라인 전체를 핑퐁한다. 성능이 10배 추락하는 가장 흔한 사인이다.

#[repr(align(64))]
struct PaddedCounter(AtomicU64);

이렇게 64바이트 정렬로 분리하면 사라진다.

3.5 Data-Oriented Design — 게임 엔진이 발견한 진실

OOP가 만든 Entity { name, pos, vel, hp, ... }는 캐시 입장에서 악몽이다. 실제로 update_positions를 돌릴 때 필요한 건 posvel뿐인데, namehp가 캐시 라인을 오염시킨다. ECS(Entity-Component-System)와 SoA(Struct-of-Arrays)는 이 문제를 구조적으로 해결한다.

// AoS: Entity entities[N]  → 캐시 낭비
// SoA: float xs[N], ys[N], vxs[N], vys[N]  → 순수 적재

Unity DOTS, Unreal Mass Entity, Bevy ECS가 이 설계를 밀고 있다.

4부. 브랜치 예측 — 분기가 10배 느려지는 순간

4.1 왜 예측이 필요한가

파이프라인 15단계라면, if 분기를 만난 순간 "어느 쪽으로 갈지 모름"이다. CPU는 멈추는 대신 한쪽을 찍고 계속 간다. 맞으면 손해 없음, 틀리면 15 사이클 낭비.

4.2 2-bit 포화 카운터에서 TAGE까지

Stack Overflow의 유명한 질문 "왜 정렬된 배열이 정렬 안 된 배열보다 빠른가"의 답이 이것이다. 정렬된 배열은 if 분기 패턴이 예측 가능해서 예측 정확도가 100%에 가깝고, 랜덤 배열은 50%다.

4.3 Branchless 프로그래밍

핫 루프에서 분기를 제거하면 예측 실패 비용이 0이 된다.

// branch
int max = a > b ? a : b;

// branchless (CMOV)
int max = b ^ ((a ^ b) & -(a > b));

Rust/LLVM은 단순한 삼항 연산자라면 cmov로 자동 컴파일한다. 복잡해지면 SIMD로 전체 분기 자체를 벡터화한다.

5부. 2018년 이후 — Meltdown, Spectre, MDS, Zenbleed

5.1 Meltdown (Intel)

유저 모드에서 커널 메모리를 투기적으로 읽고 → 캐시 상태 차이로 값을 유추. Intel CPU가 권한 체크보다 먼저 데이터를 로드하는 버그. KPTI(Kernel Page Table Isolation) 패치로 5~30% 성능 하락.

5.2 Spectre v1/v2

브랜치 예측을 공격자가 조작 → 희생자 프로세스의 메모리를 캐시 사이드 채널로 추출. 하드웨어 설계 자체의 결함이라 "완전 해결 불가", mitigation만 누적되는 중(IBRS, STIBP, retpoline).

5.3 MDS, L1TF, ZombieLoad, Zenbleed

2019~2023년에 드러난 variant들. 하이퍼스레딩(SMT)을 끄는 클라우드 프로바이더가 생겼을 정도. AWS Nitro, Google Titan, Azure Pluton은 이 위협 모델에 맞춰 설계된 전용 보안 칩.

5.4 Post-Quantum 시대 보안 칩

Apple Secure Enclave, Intel SGX/TDX, AMD SEV-SNP, ARM CCA는 CPU 내부에 격리된 실행 환경을 만들어 커널조차 못 보게 한다. Confidential Computing(4부 포스트 시리즈 대형 테마)의 하드웨어 기반.

6부. Apple Silicon — M1은 왜 Intel을 이겼나

6.1 설계 비결 5가지

  1. wide decode (10-wide vs Intel 6-wide) — x86은 가변 길이 명령어 때문에 디코더 병렬화가 어렵지만 ARM은 고정 32-bit라 쉽다
  2. Unified Memory Architecture (UMA) — CPU·GPU·NPU가 같은 LPDDR에 접근, 복사 비용 0
  3. 거대한 ROB + 많은 물리 레지스터 — out-of-order 윈도우가 Intel 대비 2배
  4. SoC 수준 통합 — 메모리 컨트롤러·Thunderbolt·NVMe·Display가 한 다이, 레이턴시 붕괴
  5. TSMC 5nm/3nm 선공정 — 동일 전력에서 20~30% 앞서 시작

6.2 P-core / E-core 하이브리드

M-시리즈는 고성능 코어와 고효율 코어를 섞어 둔다. 백그라운드 작업(Spotlight 인덱싱, 메일 체크)은 E-core에 내려 배터리를 지키고, 포그라운드 연산만 P-core에 올린다. 윈도우/리눅스에서 이 스케줄링이 복잡한 이유는 OS가 워크로드 성격을 추론해야 하기 때문(Intel의 Thread Director가 도움).

6.3 Graviton/Ampere — 클라우드가 ARM으로 이동 중

AWS Graviton3/4는 동일 성능에서 30~40% 저렴하다. Netflix·Snap·Airbnb가 대규모 전환. Cloudflare Workers가 ARM 우선. 이유는 단순하다 — 와트 당 성능(performance per watt)이 절대적으로 앞선다.

7부. x86 vs ARM vs RISC-V — 2025년의 지형

7.1 x86이 남은 이유

하지만 전성비 싸움에서 ARM에게 밀리는 중. Intel은 Lunar Lake(2024)부터 메모리를 온패키지로 올리는 등 Apple 방식을 모방.

7.2 ARM이 이기는 전선

7.3 RISC-V — 오픈 ISA의 반란

관건은 RVA23 프로파일 표준화. Linux 커널은 이미 완벽히 지원.

8부. SIMD — 벡터 명령으로 8배 빠르게

8.1 왜 SIMD가 필요한가

스칼라 CPU는 한 번에 한 값. SIMD는 한 명령어로 여러 값을 동시에 처리(Single Instruction, Multiple Data).

8.2 자동 벡터화와 수동

LLVM/GCC는 단순 루프를 자동 벡터화한다. 하지만 의존성이 있거나 분기가 섞이면 실패. 성능이 절실하면 intrinsics 또는 std::simd(Rust portable SIMD, 2024 nightly), std::experimental::simd(C++)를 쓴다.

use std::simd::f32x8;
let a = f32x8::from_array([1.0; 8]);
let b = f32x8::from_array([2.0; 8]);
let c = a + b;  // 한 명령어로 8개 덧셈

8.3 실전 사례

9부. GPU 아키텍처 — CUDA 코어, SM, Warp

9.1 CPU와 GPU의 철학 차이

GPU는 캐시 미스가 나면 다른 스레드로 스위칭한다. 즉 레이턴시를 숨긴다. CPU는 캐시 미스가 나면 기다릴 뿐이다.

9.2 H100/B200/GB300 내부 구조

9.3 Warp Divergence — GPU의 브랜치 비용

같은 warp의 32 스레드가 서로 다른 분기를 타면 양쪽을 모두 실행한 뒤 마스크로 버린다. 즉 분기 비용이 극악. LLM 커널들이 branchless로 짜여진 이유.

9.4 LLM inference의 병목

9.5 ROCm·Apple MLX·Metal — NVIDIA 외 생태계

10.1 DDR5 · LPDDR5X · HBM3e

10.2 NUMA의 함정

소켓이 2개 있는 서버에서 다른 소켓 메모리 접근은 2~3배 느리다. Linux numactl, mbind 등으로 조정. 쿠버네티스 Topology Manager가 이걸 인지.

2024년부터 현실화된 표준.

의미: "서버 안의 RAM이 공유 자원"이 된다. 메모리 과프로비저닝을 전체 랙 단위로 해결.

GPU 간 직결. H100 NVLink 900 GB/s, B200 1.8 TB/s. 대규모 LLM 학습에서 병렬 전략(TP/PP/EP)이 가능한 하드웨어 기반.

11부. 전력·열·양자 — 왜 클럭이 더 이상 안 오르는가

11.1 Power Wall과 Dennard Scaling의 종말

2006년쯤 Dennard Scaling(트랜지스터 작아질수록 전력도 비례해 감소)이 멈췄다. 그 뒤로 클럭은 3~5GHz에서 고착. 해결책은 병렬화(코어 늘리기)와 특화(NPU, Tensor Core).

11.2 다크 실리콘

200억 트랜지스터가 있어도 전력 예산상 동시에 켜는 건 일부뿐. 그래서 용도별 전용 블록(AMX, NPU, 미디어 엔진)을 박아 꺼 놨다가 필요할 때만 킨다.

11.3 3D 패키징

TSMC CoWoS, Intel Foveros — 로직과 메모리를 수직 적층해 레이턴시/대역폭 폭발. B200, MI300X 모두 3D 어셈블리.

11.4 양자 컴퓨팅 — 2025년 현실

IBM Osprey(433 qubit), Google Willow(2024, 105 qubit + 오류 보정 돌파), Atom Computing 1000 qubit neutral atom. "암호 깨기까지 아직 멀었지만 최적화/화학 문제에서 유용성 보임" 단계. 소프트웨어 엔지니어에게 당장의 영향은 post-quantum crypto(Kyber, Dilithium) 준비.

12부. 이 모든 걸 성능에 어떻게 꿰는가 — 측정·프로파일·튜닝

12.1 Linux perf

perf stat -d ./myapp
# instructions, cycles, IPC, cache-misses, branch-misses
perf record -g ./myapp && perf report

12.2 Intel VTune, AMD uProf, Apple Instruments

Top-Down 분석법: Retiring / Bad Speculation / Frontend Bound / Backend Bound. 네 버킷 중 어디에 병목이 있는지 1분에 판단.

12.3 마이크로벤치의 함정

std::chrono로 100만 번 돌려 평균? 컴파일러가 loop-invariant로 판단해 코드 자체를 날려버린다. black_box (Rust), benchmark::DoNotOptimize (Google Benchmark)로 방지.

12.4 성능 작업 체크리스트

13부. 실전 — 왜 같은 언어에서 같은 알고리즘인데 10배 차이나는가

13.1 사례 1: 해시맵 선형 프로빙 vs chaining

std::unordered_map 같은 chaining은 캐시 미스의 온상. 오픈 어드레싱(linear probing)이 현대 CPU에서 2~5배 빠르다. Rust의 hashbrown(std HashMap 기반, Google SwissTable 포팅)이 대표 사례.

13.2 사례 2: JSON 파서가 1 GB/s가 가능한 이유

simdjson은 AVX-512/ARM NEON으로 한 번에 64바이트를 스캔해 구조를 파악하고, 두 번째 패스에서 파싱. 전통적 파서 대비 10배 이상.

13.3 사례 3: Redis vs KeyDB vs Dragonfly

Redis는 싱글 스레드. KeyDB/Dragonfly는 io_uring + shared-nothing으로 코어 당 선형 확장. 10~25배 스루풋 차이를 같은 하드웨어에서 낸다.

13.4 사례 4: LLM 추론 — TensorRT-LLM vs vLLM vs SGLang

14부. 하드웨어 변화가 소프트웨어 설계에 미치는 영향

14.1 NVMe + io_uring = 파일 I/O의 부활

디스크가 빨라지면서 블로킹 I/O 오버헤드가 병목. 비동기 I/O가 필수(앞선 OS 글 참고).

14.2 100 Gb/s NIC + RDMA + DPDK

네트워크가 PCIe보다 빨라지는 시대. 커널 바이패스(DPDK), RDMA(RoCEv2) 없이는 성능을 못 낸다. Cloudflare, Meta, Stripe의 엣지가 이 기술로 돌아감.

14.3 DPU/IPU

NVIDIA BlueField, Intel IPU, AWS Nitro — 네트워크/스토리지/보안을 CPU에서 분리한 전용 프로세서. 2025년 데이터센터 표준 디자인.

14.4 AI 가속기 춘추전국

NVIDIA B200/GB300, AMD MI350X, Google TPU v5p/v6, AWS Trainium2/Inferentia3, Cerebras WSE-3, Groq LPU, Tenstorrent. 각자 "한 분야에서 NVIDIA를 이긴다"가 목표.

15부. 체크리스트 12 · 안티패턴 10

✅ 체크리스트 12

  1. 핫 경로의 데이터 구조가 캐시 친화적인가? (배열 > linked list)
  2. Struct 레이아웃이 64바이트 정렬·패딩을 고려했는가?
  3. 멀티스레드 공유 데이터에 false sharing은 없는가?
  4. 핫 루프의 분기 예측률을 perf로 확인했는가?
  5. IPC가 1 미만이면 왜인지(캐시? 분기? 의존성?) 조사했는가?
  6. SIMD 기회가 있는 루프에 자동 벡터화가 성공했는가?
  7. NUMA 시스템이라면 numactl/topology manager로 로컬 메모리 고정했는가?
  8. 가상화/클라우드 vCPU의 SMT 노이즈 이웃 영향을 측정했는가?
  9. GPU 워크로드의 Warp divergence를 측정했는가?
  10. 메모리 할당을 arena/slab으로 묶어 fragmentation을 줄였는가?
  11. post-quantum crypto 전환 로드맵이 있는가? (2030 타임라인)
  12. ARM64 빌드(CI/CD)와 벤치가 준비됐는가?

⚠️ 안티패턴 10

  1. 벤치 없이 "Rust는 빠르다"라는 믿음으로 결정
  2. OOP AoS만 쓰고 SoA 고려 안 함
  3. 핫 루프에 HashMap 남발
  4. 아토믹 카운터 하나에 모든 스레드 경합
  5. 가상 스레드·async가 CPU-bound 문제를 해결한다고 생각
  6. x86에서 튜닝하고 ARM을 테스트 안 함
  7. GPU 코드에서 if-else로 warp divergence 유발
  8. memcpy 최적화에 시간 쓰고 알고리즘을 방치
  9. KVM/VM 내부 벤치를 베어메탈처럼 신뢰
  10. Meltdown/Spectre mitigation을 성능 때문에 전면 해제

다음 글 예고 — "관측가능성의 현대" — OpenTelemetry·eBPF continuous profiling·Grafana LGTM·Pyroscope·Sentry Performance·Datadog·Honeycomb·SLO·SRE·온콜

CPU를 배웠으니 "그 CPU 위에서 뭐가 일어나는지 실시간으로 보는 법"이 필요하다. 다음 글은 2025년의 관측가능성을 파낸다.

하드웨어에서 소프트웨어로, 소프트웨어에서 운영으로 — 스택의 다음 층으로 올라간다.

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다