본문으로 건너뛰기
Embedded Performance Engineering · 9/57

CPU 파이프라인 분석 — 5-stage·Cortex-M·Cortex-A 비교

· Hawk · 5분 읽기

#한 줄 요약

Pipeline은 명령어 병렬화입니다. 한 사이클당 한 명령어 완료가 목표입니다.

#5-Stage Classic Pipeline (MIPS R3000)

Stage작업
F (Fetch)PC가 가리키는 memory에서 명령어를 읽습니다
D (Decode)opcode를 해독하고 register를 read합니다
E (Execute)ALU 연산을 수행합니다
M (Memory)load/store 시 메모리에 액세스합니다
W (Writeback)register file에 결과를 씁니다
Time: 1 2 3 4 5 6 7 8
Inst1: [F] [D] [E] [M] [W]
Inst2: [F] [D] [E] [M] [W]
Inst3: [F] [D] [E] [M] [W]
Inst4: [F] [D] [E] [M] [W]

이상적으로는 매 cycle마다 1 명령이 완료됩니다 (IPC = 1.0).

실제로는 데이터 의존성 때문에 stall이 발생합니다. 다음은 RAW(Read-After-Write) hazard 하나로 뒤따르는 명령들이 한 cycle씩 밀리는 모습입니다.

5-stage pipeline에 RAW hazard 하나가 들어왔을 때의 stall 전파

#Cortex-M0/M0+ — 2-Stage

[Fetch] → [Execute (Decode+Execute+WB 통합)]

매우 단순한 구조라서 작은 die와 낮은 전력이 특징입니다. 분기 시 1 cycle을 손실합니다.

#Cortex-M3/M4 — 3-Stage

[Fetch] → [Decode] → [Execute (E+M+W 통합)]
ldr r0, [r1] ; F D E
add r2, r0, r3 ; F D E ← r0 사용

r0 의존성이 있지만 load 결과가 같은 cycle에 ALU로 전달됩니다 (forwarding). Stall 없이 진행됩니다.

#Cortex-M7 — 6-Stage Dual-Issue

F1 → F2 → D → I → E1 → E2
  • F1·F2는 분리된 fetch입니다 (캐시 line 단위).
  • D·I는 Decode와 Issue를 합칩니다 (2 instruction 동시).
  • E1·E2는 ALU와 2nd ALU 또는 Load Store입니다.

Dual-issue로 IPC > 1이 가능합니다 (이론적으로 2.0).

#Cortex-A53 — 8-Stage In-Order

F1 F2 F3 D1 D2 I E1 E2

In-order 발행에 dual-issue를 더한 구조입니다. 적당한 성능과 낮은 전력이 특징이며, Raspberry Pi 3B의 BCM2837에 들어 있습니다.

#Cortex-A72 — 15-Stage Out-of-Order

F1 F2 F3 F4 F5 D1 D2 D3 Dispatch [Issue Queue]
[Multiple Execution Units]
[Reorder Buffer]
Commit
  • 5-stage fetch로 깊은 branch prediction을 지원합니다.
  • Out-of-order issue로 의존성이 없는 명령을 먼저 실행합니다.
  • 4-wide superscalar로 동시에 4 명령을 처리합니다.

성능이 높지만 전력 소모도 그만큼 큽니다.

#Pipeline 길이 Trade-off

길이장점단점
짧음 (3)Branch miss penalty가 작습니다클럭 속도 한계가 있습니다
중간 (8)균형이 잡힙니다
김 (15+)고클럭이 가능합니다 (1.5 GHz↑)Mispredict penalty가 큽니다

Pentium 4는 31 stage였습니다. mispredict 시 31 cycle을 손실했고, 결국 실패한 디자인이 되었습니다.

#Throughput vs Latency

Tno pipeline=5N cycle,T5-stage pipe=5+(N1)=N+4 cycle (N1)T_{\text{no pipeline}} = 5N \text{ cycle}, \quad T_{\text{5-stage pipe}} = 5 + (N-1) = N + 4 \text{ cycle} \ (N \gg 1)

N=1000이면 pipeline은 200x throughput을 냅니다. 다만 latency (한 명령의 완료 시간)는 동일하거나 길어집니다.

#Pipeline Hazard 3종

#1. Structural Hazard

같은 hardware 자원을 두 명령이 동시에 사용하는 경우입니다. 예를 들어 단일 memory port에 F와 M이 동시 액세스하는 상황입니다.

해결책은 Harvard architecture입니다 (I-cache와 D-cache 분리).

#2. Data Hazard

add r0, r1, r2 ; r0 = r1 + r2
sub r3, r0, r4 ; r0 사용 — 앞 명령 결과 필요

add의 W 단계가 끝나기 전에 sub이 r0를 읽으려 합니다. forwarding이나 stall로 해결합니다.

#3. Control Hazard

beq r0, r1, label ; 분기 — 어디로 갈지 D 단계 후에야 알 수 있음
add r2, r3, r4 ; ← 미리 fetch했지만 분기 시 무효

branch prediction으로 해결합니다 (다음 편에서 다룹니다).

#ARM Forwarding (Cortex-M4)

ldr r0, [r1] ; F D E M W (load 완료 = W)
mul r2, r0, r3 ; F D D' E M W ← stall 1 cycle (load-use)

Load 결과는 forwarding이 불가능하여 1 cycle bubble이 생깁니다. 컴파일러가 재정렬을 시도합니다.

ldr r0, [r1] ; F D E M W
nop ; bubble 채움 (또는 독립 명령)
mul r2, r0, r3

#측정 — Cortex-M7 IPC

DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
uint32_t start = DWT->CYCCNT;
loop_kernel();
uint32_t cycles = DWT->CYCCNT - start;
uint32_t insts = count_instructions_in_loop();
float ipc = (float)insts / cycles;

목표 IPC는 다음과 같습니다.

  • Cortex-M0: ~0.7
  • Cortex-M3: ~0.9
  • Cortex-M4: ~0.95
  • Cortex-M7 (dual-issue): ~1.5
  • Cortex-A72 (OoO): ~3.0

#SuperH vs ARM Pipeline 차이

ARMSuperH SH-2/4
Load delay slot이 묵시적입니다Delay slot이 명시적입니다 (branch 후 명령 항상 실행)
Conditional execution (Thumb-2)이 있습니다없습니다
32 register16 register

옛 자동차 ECU의 SH-4는 delay slot이 명시적이라 컴파일러가 명시적으로 처리해야 했습니다.

#자주 하는 실수

⚠️ Pipeline 깊이가 성능과 같지는 않음

Cortex-M7 6-stage가 Cortex-M3 3-stage보다 클럭당 더 빠른 건 아닙니다. Dual-issue를 활용했을 때만 그렇습니다.

⚠️ NOP으로 stall 해결 시도

ldr r0, [r1]
nop
nop
add r2, r0, r3

컴파일러가 이미 더 잘 최적화합니다. 직접 NOP을 삽입하는 것은 보통 비최적입니다.

⚠️ 짧은 함수가 빠르다고 가정

함수 호출은 pipeline flush 가능성이 있습니다. 인라인이 더 빠릅니다. inline이나 LTO로 컴파일러를 도와줍니다.

⚠️ Cycle 측정 오류

DWT CYCCNT는 DMB와 DSB 없이는 정확하게 측정되지 않습니다. barrier를 추가합니다.

__DSB();
uint32_t start = DWT->CYCCNT;
/* code */
__DSB();
uint32_t end = DWT->CYCCNT;

#정리

  • Pipeline은 명령어 단계별 병렬화입니다 (F·D·E·M·W).
  • Cortex-M0는 2-stage, M3/M4는 3-stage, M7은 6-stage dual-issue입니다.
  • Cortex-A는 8~15-stage의 out-of-order superscalar입니다.
  • 3 hazard (structural·data·control)는 forwarding과 branch prediction으로 회피합니다.
  • Pipeline 깊이는 trade-off가 있습니다. 길수록 클럭이 높아지지만 mispredict 비용도 커집니다.

다음 편은 Pipeline Stall입니다. Data dependency를 자세히 다룹니다.

#관련 항목

Embedded Performance Engineering · 10 of 57

  1. 1Embedded Performance Engineering — 임베디드 성능 엔지니어링 시리즈 소개
  2. 2임베디드 성능 분석 방법론 — Measure → Analyze → Optimize 사이클
  3. 3성능 지표 정의 — Latency·Throughput·Utilization 분석
  4. 4성능 측정의 기본 — Wall-Clock·CPU Cycle·Instruction Count
  5. 5성능 데이터 통계적 분석 — Percentile·Histogram·평균의 함정
  6. 6실시간 성능 분석 — WCET·Jitter·Deadline Miss 측정
  7. 7임베디드 벤치마킹 기초 — 재현성·Warmup·노이즈 제거
  8. 8성능 모델링 — Amdahl·Gustafson·Roofline Model 적용
  9. 9프로파일링 기법 개요 — Sampling vs Instrumentation·PGO·LTO
  10. 10CPU 파이프라인 분석 — 5-stage·Cortex-M·Cortex-A 비교
  11. 11Pipeline Stall 분석 — Data·Structural·Control Hazard·Forwarding
  12. 12Branch Prediction 분석 — Static·2-bit·BTB·BHT·Mispredict 비용
  13. 13Speculative Execution 분석 — OoO·Reorder Buffer·Register Renaming
  14. 14CPU Cache 기초 — L1·L2·L3·Set Associative·Replacement Policy
  15. 15Cache Miss 3C Model 분석 — Compulsory·Capacity·Conflict
  16. 16Cache Line 최적화 — Alignment·Prefetch·False Sharing 처리
  17. 17메모리 대역폭 분석 — STREAM·Roofline·Bus Saturation 측정
  18. 18SIMD·NEON 활용 — 128-bit Vector·Auto-Vectorization·SVE/SVE2
  19. 19PMU·HPM 하드웨어 카운터 분석 — 정밀 성능 진단
  20. 20임베디드 Bus Architecture — AHB·AXI·CHI 진화와 5-Channel
  21. 21Bus Contention 진단 — Arbitration·QoS·Starvation 측정
  22. 22DMA 성능 최적화 — Burst·Scatter-Gather·Chain·Cache 일관성
  23. 23DMA vs CPU Copy 성능 비교 — Break-even·Setup Overhead 실측
  24. 24Interrupt Latency 분석 — 진입·종료·Tail-Chaining·Late Arrival
  25. 25Interrupt Storm 처리 — NAPI·Rate-Limit·Polling 전환
  26. 26MMIO 접근 성능 — Cache Policy·Write-Combining·Volatile·Barrier
  27. 27Peripheral Clock 분석 — PLL·Divider·Gating·DVFS
  28. 28Power vs Performance 트레이드오프 — DVFS·Race-to-Idle·Big.LITTLE
  29. 29Thermal Throttling 분석 — Junction Temp·Trip Point·냉각
  30. 30CXL Interconnect 분석 — AI 시대 메모리 대역폭 확장
  31. 31Concurrency 기초 — Concurrency vs Parallelism·Race·Memory Model
  32. 32False Sharing 진단 — Cache Line Ping-Pong·Padding·측정
  33. 33Lock Contention 분석 — Wait·Hold·Convoy·측정 기법
  34. 34Spinlock 성능 분석 — Spin-Wait vs Context Switch·Ticket·MCS
  35. 35Mutex 성능 분석 — Futex·Adaptive·Priority Inheritance
  36. 36Reader-Writer Lock 성능 — Reader/Writer Priority·RCU·Seqlock
  37. 37Lock-Free 자료구조 성능 — CAS·ABA·Hazard Pointer·Epoch Reclamation
  38. 38Memory Ordering 분석 — Acquire·Release·Seq-Cst·ARM Relaxed Model
  39. 39Cache Coherency 프로토콜 — MESI·MOESI·Snoop·Directory
  40. 40SMP 성능 분석 — Per-Core·Affinity·Load Balance·Scalability
  41. 41Linux perf 기초 — stat·record·report 활용
  42. 42Linux perf 고급 — Raw Event·Tracepoint·perf script
  43. 43ftrace 활용 — function·function_graph·latency tracer
  44. 44eBPF·bpftrace 동적 트레이싱 — 커널 무수정 관측
  45. 45Flamegraph 분석 — On-CPU·Off-CPU·Differential
  46. 46ARM DS·Lauterbach 분석 — Hardware Trace 전문 도구
  47. 47Bare-metal 프로파일링 — GPIO·DWT·SysTick·ITM 활용
  48. 48NVIDIA Nsight Systems — GPU·NPU 포함 시스템 분석
  49. 49모던 프로파일러 비교 — Tracy·Hotspot·uftrace·Coz
  50. 50연속 프로파일링 — Parca·Pixie·Pyroscope·Tetragon
  51. 51실전 사례 — ISR Latency 100µs Deadline Miss 추적
  52. 52실전 사례 — Matrix Multiply가 예상의 10배 느린 이유
  53. 53실전 사례 — 8-core가 4-core를 넘으면 throughput이 떨어지는 이유
  54. 54실전 사례 — 카메라 1080p 60fps가 30fps로 떨어지는 이유
  55. 55CXL.mem 지연·대역폭 실측 — Direct·Switch·Pooled 토폴로지 비교
  56. 56CXL 성능 프로파일링 도구 — cxl-cli·DAMON·perf-mem 활용
  57. 57실전 사례 — CXL.mem 추가로 LLM inference KV cache 처리량 회복