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

Speculative Execution 분석 — OoO·Reorder Buffer·Register Renaming

· Hawk · 5분 읽기

#한 줄 요약

**“Speculation = 미래 예측 실행”**입니다. 결과가 맞으면 commit하고 틀리면 rollback합니다.

#In-Order vs Out-of-Order

ldr r0, [r1] ; load — cache miss 가능 (100+ cycle)
add r2, r3, r4 ; r0 무관 — 독립
sub r5, r6, r7 ; 독립
mul r8, r0, r9 ; r0 의존 — load 완료까지 대기

#In-Order (Cortex-M, Cortex-A53)

ldr r0, [r1] ████████████████ (cache miss 동안 모두 stall)
add r2, ... stall
sub r5, ... stall
mul r8, ... 실행

#Out-of-Order (Cortex-A72, Apple M1)

ldr r0, [r1] ████████████████
add r2, ... ██ (먼저 실행 — r0 무관)
sub r5, ... ██
mul r8, ... stall → ldr 완료 후 실행

Load latency hiding 기법입니다. 메모리 대기 동안 다른 명령을 실행해 IPC를 끌어올립니다.

#OoO 핵심 구성요소

Out-of-Order 실행 구조 — Fetch, Decode, Issue Queue, Execution Units, ROB, Commit

#Register Renaming

ISA 레벨에서 r0는 16개입니다. 그러나 OoO에서는 physical register (Cortex-A72는 90개)로 mapping합니다.

ISA: add r0, r1, r2 → physical: p10 = p1 + p2 (rename r0→p10)
sub r3, r0, r4 → physical: p11 = p10 + p4 (r0=p10 lookup, rename r3→p11)
add r0, r5, r6 → physical: p12 = p5 + p6 (rename r0→p12 — WAW 해소)

WAR·WAW 의존성이 제거되어 진짜 RAW만 남습니다.

#Reorder Buffer (ROB)

ROB entry (in fetch order):
[add ✓ r0=12] [sub ✓ r3=10] [ldr ⏳ r1=?] [add ⏳] [mul ⏳]
↑ load miss — 대기
이미 실행 완료된 sub, add는 *ROB에 대기*. ldr 완료 후 *순서대로 commit*.

ROB 크기는 곧 OoO window입니다. Cortex-A72는 128 entry이고 Apple M1은 630+ entry로 괴물 수준입니다.

#Speculative Load — Load Hoisting

if (ptr != NULL) {
x = ptr->field; // ← branch 확정 전에 미리 load
}

Modern CPU는 branch resolve 전에 미리 load를 실행합니다. Branch 예측이 맞으면 결과를 사용하고, 틀리면 결과를 폐기합니다. 다만 cache 상태는 그대로 남습니다.

이것이 Spectre v1의 토대입니다.

#Wrong-Path Execution

beq r0, r1, taken ; branch
not_taken_path: ; 미리 fetch + speculative execute
add ...
sub ...
ldr [r2] ; speculative load — cache 영향
taken:
...

분기를 잘못 예측하면 not-taken path의 명령이 모두 rollback됩니다. 그러나 cache는 update된 채로 남습니다.

Spectre exploit는 비밀 데이터를 speculative path에서 cache로 끌어온 뒤, cache timing 측정으로 정보를 leak합니다.

#Memory Disambiguation

str r0, [r1] ; store
ldr r2, [r3] ; load — r1 == r3?

OoO에서 load를 store 앞으로 보낼 수 있을까요? 주소가 같지 않으면 OK입니다. 주소가 같으면 forwarding하거나 stall합니다.

Store Queue:

  • [addr=0x1000, data=42, ✓]
  • [addr=0x1004, data=99, ✓]

Load:

  • addr=0x1000 → Store Queue match → forward 42 (memory 안 가도 됨)
  • addr=0x2000 → no match → memory access

Cortex-A72는 Memory Order Buffer (MOB)로 store/load 순서를 관리합니다.

#Speculative Execution의 측정

Terminal window
perf stat -e instructions,cycles,br_pred_retired,br_misp_retired ./prog
# IPC = instructions / cycles
# Cortex-A72 ideal: 2-3
# 실제 일반 코드: 1.5-2

낮은 IPC와 낮은 mispredict rate가 함께 나타나면 memory bound 또는 data dependency가 원인입니다.

#ARM Cortex-A72 OoO Spec

항목
Fetch width3
Decode/Rename3-wide
Issue queue32-entry
ROB128-entry
Physical registers90 (int) + 128 (fp)
Execution units2 ALU + 1 LSU + 1 FPU + 1 NEON
ALU latency1 cycle
Load latency4 cycle (L1 hit)

#OoO 단점

단점영향
전력Rename·ROB·issue queue = die area 2-3배
검증 비용의존성·forwarding 경우의 수 폭증
Spectre·Meltdownspeculation 부작용
WCET 예측 곤란분석 어려움 → 안전성 critical 시스템 회피

자동차·항공기 flight control은 OoO를 회피하고 in-order Cortex-R5나 Cortex-A53 in-order를 사용합니다.

#In-Order의 부활 — Embedded·자동차

CPUOoO?용도
Cortex-R5In-order자동차 brake·airbag
Cortex-A53In-order라즈베리 파이 3, 저전력 SoC
Cortex-R52In-order자동차 ASIL D ECU
Cortex-A72OoOLinux server, 라즈베리 파이 4
Cortex-A78OoO모바일 flagship

Determinism이 중요한 곳은 in-order.

#RISC-V — OoO 옵션

CoreOoO?
SiFive E31 (마이크로컨트롤러)In-order
SiFive U54 (Linux)In-order
SiFive U74 (개선)In-order, dual-issue
SiFive U84·P870OoO
Berkeley BOOMOoO (open source)

오픈소스 BOOM은 academic OoO RISC-V로 학습용으로 좋습니다.

#자주 하는 실수

⚠️ OoO = 항상 빠름

저전력 임베디드는 전력당 성능 면에서 in-order가 더 빠를 수 있습니다. 특히 짧은 코드나 예측 가능한 path에서는 OoO overhead가 더 큽니다.

⚠️ Spectre 무시

Linux server나 multi-tenant 환경에서는 Spectre mitigation이 필수입니다 (RETBLEED·SBB 패치). 임베디드의 fully trusted 환경에서는 비활성화도 가능합니다.

⚠️ Speculation barrier 남발

__asm__("dsb sy; isb"); // 매 라인 → OoO 효과 무력화

특정 보안 critical 지점에만 적용합니다. 일반 코드는 컴파일러가 알아서 처리합니다.

⚠️ WCET = average

OoO CPU에서는 worst case가 average보다 훨씬 큽니다. 자동차·항공 인증에는 별도의 WCET 분석 도구가 필요합니다 (aiT, Bound-T).

#정리

  • OoO에서는 issue 순서와 완료 순서가 다릅니다. ROB가 in-order commit을 담당합니다.
  • Register renaming으로 WAR·WAW 의존성을 제거합니다.
  • Speculation은 branch·load 예측 실행이며 Spectre 위험을 동반합니다.
  • In-order와 OoO의 trade-off는 결정성·전력과 성능 사이의 선택입니다.
  • 안전 critical 영역(브레이크·비행 제어)은 in-order를 선호합니다.

다음 편은 Cache 기초입니다.

#관련 항목

Embedded Performance Engineering · 13 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 처리량 회복