Bus Contention 진단 — Arbitration·QoS·Starvation 측정
#한 줄 요약
**“Contention = 여러 master가 한 slave에 동시에 접근하는 상황”**입니다. arbiter는 공평과 빠름 사이에서 trade-off를 선택합니다.
#Arbitration 정책
#Round-Robin (Fair)
Master: A B C DToken: ↑ ──→Cycle 1: A (token=A)Cycle 2: B (token=B)Cycle 3: CCycle 4: DCycle 5: A장점은 공평하고 굶주림이 없다는 점입니다. 단점은 우선순위를 지정할 수 없다는 점입니다.
#Priority
Master: A (P0) B (P1) C (P2) D (P3) ↑ highest
A·B·C·D 동시 요청 → D 먼저장점은 critical master를 보장한다는 점입니다. 단점은 low priority master가 starvation에 빠질 수 있다는 점입니다.
#Weighted Round-Robin
Master A weight=3, B weight=1, C weight=1순환: A A A B C A A A B C ...대역폭을 정해진 비율로 분배하는 방식입니다.
#QoS-Based (AXI)
ARM CCI-400과 CMN의 표준 방식이며, Cortex-A SoC에서 흔히 사용합니다.
#Cortex-A SoC — CCI-400 사례
[Cluster 0 (4 × A72)] AXI ─→ [CCI-400] ─→ DDR Controller[Cluster 1 (4 × A53)] AXI ─→[GPU] AXI ─→[DPU (display)] AXI ─→[VPU (video)] AXI ─→CCI-400은 5 master와 3 slave까지 지원합니다. master별 QoS regulator와 bandwidth limiter를 함께 제공합니다.
/* CCI-400 register */CCI->QoS[CLUSTER0] = 0xC; // medium-highCCI->QoS[DPU] = 0xF; // highest — frame drop 방지CCI->QoS[GPU] = 0x8; // medium#STM32H7 — AXI Bus Matrix
Slave 6개, master 7개로 42 path가 만들어집니다. 각 path별로 fixed priority 또는 round-robin을 설정합니다.
- 기본 — round-robin
- critical (LTDC for display) — fixed high priority
/* HAL */__HAL_RCC_AXI_CLK_ENABLE();HAL_AXIBusMatrix_ConfigPriority(M5_LTDC, AXI_PRIORITY_HIGH);#Starvation 시나리오
다음과 같은 상황에서 starvation이 발생합니다.
Master A: 매 cycle DMA burst 요청 (high priority)Master B: 가끔 read 요청 (low priority)
Arbiter — A 우선 → B *수 ms 대기*B의 latency-sensitive 작업 (LCD refresh) → frame drop#해결 1: Bandwidth Limit on A
CCI->BW_REGULATOR[A] = LIMIT_50_PCT; // A는 50%만 사용A의 throughput을 일부 손실하는 대신 B의 latency를 개선할 수 있습니다.
#해결 2: Latency-based QoS
ARQOS = LATENCY_CRITICAL; // arbiter가 *delay 안 우선*CCI가 대기 시간까지 고려해서, 오래 기다린 transaction일수록 priority를 올려 줍니다.
#측정 — AXI Monitor
ARM CoreSight와 DSU PMU를 함께 활용합니다.
- BUS_ACCESS_LD / BUS_ACCESS_ST — Load/Store bus access events
- BUS_ACCESS_CHKD — 외부 bus 접근만
- BUS_CYCLES — bus active cycle
perf stat -e r19,r1d ./prog# BUS_ACCESS=10M, BUS_CYCLES=100M → 10% utilization#VTune Memory Bandwidth Analysis
VTune의 time-series chart는 다음과 같이 표시됩니다.
Time-series chart:
- CPU: ────░░░░░░░░░░░──── (10%)
- GPU: ──────░░░░░░██████ (60%)
- DMA: ░░░░░░░░░░░░░░░░██ (5%)
- Total: ░░░░░░░░██████░░ (saturation)
색칠된 부분이 active 상태입니다. 총합이 100%에 가까워지면 saturation입니다.
#DMA·CPU 충돌 해결
#TCM (Cortex-M·R) 활용
__attribute__((section(".dtcm"))) uint8_t fast_buf[8192];
void critical_isr(void) { /* DTCM은 *별도 bus* — DMA·main RAM과 충돌 없음 */ process(fast_buf);}DTCM과 ITCM은 CPU 전용 bus라서 bus matrix를 우회합니다.
#Cache Locking
/* Cortex-A53 — way locking */write_l2_lockdown(WAY_0, 1); // way 0 lock/* 특정 line이 evict 안 됨 — predictable latency */WCET 보장이 critical한 경우에 사용합니다.
#Master 분리 SoC 디자인
CPU ─→ DDR0GPU ─→ DDR1 (분리된 channel)DMA ─→ DDR2서로 다른 DDR channel로 access하면 contention이 0이 됩니다. 다만 BGA 핀 수가 늘어나 고가 SoC에서만 가능합니다.
#Cortex-M Bus Matrix — STM32 사례
Master: M0 CPU M1 DMA1 M2 DMA2 M3 Ethernet M4 USB
Slave: S0 Flash S1 SRAM1 S2 SRAM2 S3 AHB1 peripherals S4 APB1 S5 APB2
→ M0 ↔ S0 (code fetch) M1 ↔ S1 (DMA data) M2 ↔ S2 (DMA data) 동시 — *4 simultaneous transfer*bus matrix 덕분에 같은 buffer만 쓰지 않으면 대역폭이 4배까지 늘어납니다.
#QoS 동적 조정 — 자동차 사례
void on_brake_event(void) { /* 브레이크 신호 — critical */ CCI->QOS[BRAKE_ECU] = MAX_PRIORITY; /* 다른 master → 낮춤 */ CCI->QOS[INFOTAINMENT] = LOW;}차량 상태에 따라 priority를 동적으로 조정합니다. 다만 ASIL-D ECU에서는 정적으로 worst case를 보장하는 쪽을 우선합니다.
#Bandwidth Regulator
/* CCI-400 — per master */CCI->REG_THROTTLE[GPU] = TOKEN_BUCKET( .max_burst = 64, // 64 transfer .replenish_rate = 100 // 100 transfer/µs);Token bucket 방식은 peak는 허용하면서 평균을 제한합니다. GPU와 DPU에 흔히 사용하며, frame drop을 막으면서도 CPU 대역폭을 함께 보장합니다.
#자주 하는 실수
⚠️ 같은 master ID로 multi-thread
Cortex-A core 4개가 모두 ID=0으로 transaction을 발사하면 AXI가 같은 ID FIFO 순서를 강제해 OoO를 못 합니다.
Cluster와 Core별로 unique ID를 부여해야 합니다. Cortex-A72의 ARID는 cluster|core|thread로 encoding되어 있습니다.
⚠️ QoS 모든 master 최대
CCI->QOS[CPU] = 15;CCI->QOS[GPU] = 15;CCI->QOS[DMA] = 15;모두 max로 설정하면 의미가 없어집니다. 결과적으로 모두 동등해져 round-robin으로 fallback됩니다.
⚠️ Bus contention 측정 안 함
이렇게 두면 성능 문제가 CPU 부족 때문인지 bus saturation 때문인지 구분이 안 됩니다. PMU의 BUS_ACCESS와 STALL_BACKEND_MEM을 비교해야 합니다.
⚠️ DMA가 CPU 깨움 패턴
HAL_DMA_Start(...);while (!dma_done) { CPU 대기 } // CPU도 bus 점유 — 의미 없음CPU를 sleep(WFI) 상태로 두거나 다른 일을 시켜서 bus를 양보해야 합니다.
#정리
- Arbitration 방식은 round-robin, priority, weighted, QoS가 있습니다.
- AXI는 ARQOS 4-bit으로 master별 우선순위를 표현합니다.
- Starvation 방지를 위해 bandwidth regulator와 latency-based QoS를 활용합니다.
- STM32H7은 7×6 bus matrix로 parallel transfer를 지원합니다.
- 자동차 시스템에서는 상황에 따라 QoS를 동적으로 조정합니다.
- 측정은 PMU의
BUS_ACCESS와BUS_CYCLES로 수행합니다.
다음 편에서는 DMA Performance를 다룹니다.
#관련 항목
Embedded Performance Engineering · 21 of 57
- 1Embedded Performance Engineering — 임베디드 성능 엔지니어링 시리즈 소개
- 2임베디드 성능 분석 방법론 — Measure → Analyze → Optimize 사이클
- 3성능 지표 정의 — Latency·Throughput·Utilization 분석
- 4성능 측정의 기본 — Wall-Clock·CPU Cycle·Instruction Count
- 5성능 데이터 통계적 분석 — Percentile·Histogram·평균의 함정
- 6실시간 성능 분석 — WCET·Jitter·Deadline Miss 측정
- 7임베디드 벤치마킹 기초 — 재현성·Warmup·노이즈 제거
- 8성능 모델링 — Amdahl·Gustafson·Roofline Model 적용
- 9프로파일링 기법 개요 — Sampling vs Instrumentation·PGO·LTO
- 10CPU 파이프라인 분석 — 5-stage·Cortex-M·Cortex-A 비교
- 11Pipeline Stall 분석 — Data·Structural·Control Hazard·Forwarding
- 12Branch Prediction 분석 — Static·2-bit·BTB·BHT·Mispredict 비용
- 13Speculative Execution 분석 — OoO·Reorder Buffer·Register Renaming
- 14CPU Cache 기초 — L1·L2·L3·Set Associative·Replacement Policy
- 15Cache Miss 3C Model 분석 — Compulsory·Capacity·Conflict
- 16Cache Line 최적화 — Alignment·Prefetch·False Sharing 처리
- 17메모리 대역폭 분석 — STREAM·Roofline·Bus Saturation 측정
- 18SIMD·NEON 활용 — 128-bit Vector·Auto-Vectorization·SVE/SVE2
- 19PMU·HPM 하드웨어 카운터 분석 — 정밀 성능 진단
- 20임베디드 Bus Architecture — AHB·AXI·CHI 진화와 5-Channel
- 21Bus Contention 진단 — Arbitration·QoS·Starvation 측정
- 22DMA 성능 최적화 — Burst·Scatter-Gather·Chain·Cache 일관성
- 23DMA vs CPU Copy 성능 비교 — Break-even·Setup Overhead 실측
- 24Interrupt Latency 분석 — 진입·종료·Tail-Chaining·Late Arrival
- 25Interrupt Storm 처리 — NAPI·Rate-Limit·Polling 전환
- 26MMIO 접근 성능 — Cache Policy·Write-Combining·Volatile·Barrier
- 27Peripheral Clock 분석 — PLL·Divider·Gating·DVFS
- 28Power vs Performance 트레이드오프 — DVFS·Race-to-Idle·Big.LITTLE
- 29Thermal Throttling 분석 — Junction Temp·Trip Point·냉각
- 30CXL Interconnect 분석 — AI 시대 메모리 대역폭 확장
- 31Concurrency 기초 — Concurrency vs Parallelism·Race·Memory Model
- 32False Sharing 진단 — Cache Line Ping-Pong·Padding·측정
- 33Lock Contention 분석 — Wait·Hold·Convoy·측정 기법
- 34Spinlock 성능 분석 — Spin-Wait vs Context Switch·Ticket·MCS
- 35Mutex 성능 분석 — Futex·Adaptive·Priority Inheritance
- 36Reader-Writer Lock 성능 — Reader/Writer Priority·RCU·Seqlock
- 37Lock-Free 자료구조 성능 — CAS·ABA·Hazard Pointer·Epoch Reclamation
- 38Memory Ordering 분석 — Acquire·Release·Seq-Cst·ARM Relaxed Model
- 39Cache Coherency 프로토콜 — MESI·MOESI·Snoop·Directory
- 40SMP 성능 분석 — Per-Core·Affinity·Load Balance·Scalability
- 41Linux perf 기초 — stat·record·report 활용
- 42Linux perf 고급 — Raw Event·Tracepoint·perf script
- 43ftrace 활용 — function·function_graph·latency tracer
- 44eBPF·bpftrace 동적 트레이싱 — 커널 무수정 관측
- 45Flamegraph 분석 — On-CPU·Off-CPU·Differential
- 46ARM DS·Lauterbach 분석 — Hardware Trace 전문 도구
- 47Bare-metal 프로파일링 — GPIO·DWT·SysTick·ITM 활용
- 48NVIDIA Nsight Systems — GPU·NPU 포함 시스템 분석
- 49모던 프로파일러 비교 — Tracy·Hotspot·uftrace·Coz
- 50연속 프로파일링 — Parca·Pixie·Pyroscope·Tetragon
- 51실전 사례 — ISR Latency 100µs Deadline Miss 추적
- 52실전 사례 — Matrix Multiply가 예상의 10배 느린 이유
- 53실전 사례 — 8-core가 4-core를 넘으면 throughput이 떨어지는 이유
- 54실전 사례 — 카메라 1080p 60fps가 30fps로 떨어지는 이유
- 55CXL.mem 지연·대역폭 실측 — Direct·Switch·Pooled 토폴로지 비교
- 56CXL 성능 프로파일링 도구 — cxl-cli·DAMON·perf-mem 활용
- 57실전 사례 — CXL.mem 추가로 LLM inference KV cache 처리량 회복
관련 글
실전 사례 — 8-core가 4-core를 넘으면 throughput이 떨어지는 이유
8-core 서버에서 thread를 늘릴수록 throughput이 오히려 감소. 단일 global mutex가 cache invalidation 폭주를 일으킨 사례.
Lock Contention 분석 — Wait·Hold·Convoy·측정 기법
Wait time과 hold time, contention ratio를 측정하고 lock convoy를 회피하는 법.
임베디드 Bus Architecture — AHB·AXI·CHI 진화와 5-Channel
ARM AMBA — AHB·APB·AXI·ACE·CHI. AXI 5 channel, burst, outstanding transaction.