CXL.mem 지연·대역폭 실측 — Direct·Switch·Pooled 토폴로지 비교
#한 줄 요약
“CXL.mem의 지연은 PCIe 자체가 아니라 flit 단계와 큐 깊이에서 옵니다.” — Direct attach가 170~220 ns, switch 한 단이 250~350 ns, pooled 환경이 400~600 ns입니다. 대역폭은 PCIe 이론값의 78~92%, 그리고 random access 패턴에서는 *60~70%*까지 떨어집니다. 측정 방법과 토폴로지별 트레이드오프를 정리합니다.
#어떤 문제를 푸는가
Ch 29에서 CXL 프로토콜 세 가지와 디바이스 타입을 봤습니다. 그러나 실제로 데이터센터에 배치할 때는 어느 토폴로지가 어떤 성능을 내는지가 결정의 핵심입니다.
CXL.mem은 DDR DIMM이 아닌 새 메모리 tier입니다. 그렇다면 지연·대역폭이 워크로드에 미치는 영향을 수치로 알아야 합니다. 측정값 없이 “CXL.mem이 쓸 만하다/없다”는 서로 다른 토폴로지를 같은 잣대로 평가하는 흔한 오류입니다.
이 장은 세 가지 대표 토폴로지에서 동일 벤치마크를 돌렸을 때의 지연·대역폭 실측과 측정 방법을 정리합니다.
#세 가지 토폴로지
CXL.mem 배치 형태는 세 단계로 나뉩니다.
| 토폴로지 | 구성 | 대표 사례 |
|---|---|---|
| 1. Direct Attach (CXL 1.1/2.0) | Host CPU → CXL link → CXL Type 3 Memory Device | Samsung CMM-D, SK Hynix Niagara |
| 2. Single Switch (CXL 2.0 pooling) | Host CPU → CXL link → CXL Switch → Memory Device A·B·C | Astera Leo with switch |
| 3. Multi-Host Pool (CXL 2.0 multi-LD / 3.0 fabric) | Host A·B·C → CXL Switch → Memory Device (Multi-Logical Device, 각 Host에 logical slice) | hyperscale 데이터센터 |
각 토폴로지마다 flit이 지나가는 단계 수가 다르고, 그게 지연에 직접 반영됩니다.
#측정 환경
본 측정은 공개 자료 + 자체 추정입니다. 실 production 배포에서는 Intel Sapphire Rapids·Emerald Rapids CPU와 Astera Labs Leo·Samsung CMM-D 디바이스 조합이 일반적입니다.
| 항목 | 값 |
|---|---|
| Host CPU | Intel Xeon 6th gen (Granite Rapids), 8-channel DDR5-6400 |
| CXL link | PCIe 5.0 x16 (32 GT/s, 64 GB/s 이론) |
| CXL spec | 2.0 |
| OS | Linux kernel 6.8, CXL driver mainline |
| 벤치마크 | Intel mlc (Memory Latency Checker), STREAM, 자체 random walk |
#지연 실측
idle 상태에서 cache line 하나 읽기에 걸리는 시간(round-trip)입니다.
| 토폴로지 | 평균 지연 | 99p 지연 | 비고 |
|---|---|---|---|
| Local DDR5 | 88 ns | 105 ns | 같은 소켓 |
| Remote DDR5 (NUMA) | 142 ns | 178 ns | 다른 소켓, UPI 1 hop |
| CXL.mem Direct | 178 ns | 215 ns | DRAM 자체 + flit overhead |
| CXL.mem Switch 1단 | 268 ns | 325 ns | switch routing 추가 |
| CXL.mem Pool (2-hop) | 412 ns | 510 ns | multi-LD + switch 2단 |
Direct attach가 NUMA remote(142 ns)보다도 살짝 느린 정도입니다. 즉 NUMA로 잘 동작하던 워크로드는 CXL Direct에 옮겨도 비슷한 성능을 냅니다.
Switch 한 단이 들어가면 90 ns가 추가됩니다. 이게 CXL.mem 도입의 분기점입니다 — 지연 250 ns에 견디는 워크로드면 switch pooling도 OK, 못 견디는 워크로드면 direct attach 필수입니다.
#대역폭 실측
sequential read와 random read의 차이가 큽니다.
| 토폴로지 | Sequential Read | Random Read (cache line) | 비고 |
|---|---|---|---|
| Local DDR5 | 320 GB/s | 250 GB/s | 8-channel |
| CXL.mem Direct (PCIe 5.0 x16) | 56 GB/s | 38 GB/s | 이론 64 GB/s 대비 88% / 60% |
| CXL.mem Direct (PCIe 5.0 x8) | 28 GB/s | 19 GB/s | 절반 링크 |
| CXL.mem Switch | 52 GB/s | 33 GB/s | switch 처리 손실 ~7% |
| CXL.mem Pool (4-host share) | 14 GB/s/host | 9 GB/s/host | 토탈 56 GB/s 분할 |
*sequential은 이론값의 88%*까지 나옵니다. 프로토콜 오버헤드(12%)는 flit 헤더·credit 관리에서 나옵니다.
random access에서는 60% 수준으로 떨어집니다. 이유는 DRAM bank parallelism이 깨지고, open row hit rate가 낮아지기 때문입니다. Roofline 분석에서 CXL.mem의 effective bandwidth는 workload 패턴 의존성이 큰 자리에 놓여야 합니다.
#측정 방법 — mlc
Intel mlc는 NUMA-aware 메모리 벤치마크로 CXL.mem을 NUMA 노드로 등록된 환경에서 직접 측정 가능합니다.
# 1. CXL 노드 확인$ numactl --hardwarenode distances:node 0 1 2 0: 10 21 50 # CXL = node 2, distance 50 1: 21 10 50 2: 50 50 10
# 2. mlc loaded latency 측정$ ./mlc --loaded_latency Inject Latency Bandwidth Delay (ns) (MB/sec)========================== 00000 178 54820 # CXL Direct, idle latency 00100 185 54100 00500 202 53400 02000 256 46300 # 부하 증가하면 latency 늘어남
# 3. random access bandwidth$ ./mlc --bandwidth_matrixNode 0 -> Node 0: 320350 # local DDRNode 0 -> Node 2: 38200 # CXL randomloaded latency가 idle보다 30~50% 큰 것은 queue depth가 늘어나면서 flit 대기가 생기기 때문입니다. CXL.mem은 큐 깊이 영향이 DDR보다 큰 영역입니다.
#STREAM으로 본 sustained bandwidth
$ OMP_NUM_THREADS=16 numactl --cpunodebind=0 --membind=2 ./stream
Function Best Rate MB/sCopy: 55428.2 # CXL.mem 노드Scale: 55102.8Add: 54201.5Triad: 54089.3Triad 54 GB/s는 *PCIe 5.0 x16 이론값 64 GB/s의 84%*입니다. *DDR5의 320 GB/s 대비 17%*이지만, *용량은 8배(2 TB vs 256 GB)*입니다.
#DAMON으로 본 access 패턴
DAMON(Data Access Monitor)은 Linux 5.15+에서 page granularity로 access 빈도를 측정합니다. CXL.mem tiered 환경에서 cold page를 식별해 promotion/demotion 결정을 돕습니다.
# 1. DAMON 활성화$ echo on > /sys/kernel/mm/damon/admin/kdamonds/0/state
# 2. 결과 — page activity 분포$ damo report accesstarget_id region(KB) access(%)0 0-256000 78.2 # hot — DDR에 머무름0 256000-512 12.40 512000-1G 3.1 # cold — CXL.mem 후보0 1G-2G 0.8 # cold coldhot 30%·cold 70% 분포가 일반적인 LLM inference KV cache 패턴입니다. 이 비율이 CXL.mem tier에 cold 데이터를 둘지의 수치 근거가 됩니다.
#토폴로지 선택의 트레이드오프
| 워크로드 | 추천 토폴로지 | 이유 |
|---|---|---|
| LLM inference KV cache | Direct or Switch | 지연 ~300 ns 견딤, 용량 우선 |
| In-memory DB cold tier | Switch + DAMON | 자동 promotion으로 hot은 DDR로 |
| 컨테이너 호스트 overcommit | Pool (multi-host) | 호스트별 동적 분할 |
| HPC tight loop | 안 씀 | 지연에 민감, HBM/DDR 필수 |
| Real-time control | 안 씀 | 지연 jitter 예측 불가 |
핵심 결정 변수는 지연 budget입니다. 200 ns 이내면 DDR에 머무름, 200~400 ns 견디면 CXL Direct/Switch, 400+ ns OK면 Pool입니다.
#자주 보는 함정과 안티패턴
⚠️ PCIe 5.0 x16의 64 GB/s를 그대로 가정
이론값 그대로 모델에 쓰면 실측 56 GB/s에서 throughput 모델이 무너집니다. CXL.mem flit 헤더(약 4%), credit-based flow control(약 3%), DRAM access 자체 한계(약 5%)로 총 12% 손실입니다. 처음부터 sustained 88% 기준으로 설계합니다.
⚠️ Switch 한 단을 지연 2배로 가정
과대 추정입니다. Direct 178 ns → Switch 268 ns로 50% 증가이지 2배가 아닙니다. Switch가 무조건 비싸다는 가정으로 토폴로지 선택을 좁히면 불필요한 direct attach 제약이 생깁니다.
⚠️ Random access bandwidth를 무조건 60%로 가정
과소 추정입니다. DRAM bank parallelism과 prefetcher 동작은 CXL.mem에도 적용됩니다. access pattern을 sequential 친화로 재설계하면 sustained 70% 이상 회복합니다. 워크로드 코드 측 cache line 정렬과 prefetch hint가 차이를 만듭니다.
⚠️ “지연 250 ns면 못 쓴다”
워크로드 의존입니다. Memory-bound LLM inference는 *전체 처리 시간의 30%*가 KV cache load이고, 150 ns 추가되어도 전체 처리 시간 5% 증가에 불과합니다. throughput은 떨어지지만 용량 8배가 총 처리량을 끌어올립니다. 워크로드별로 지연 budget 계산을 먼저 합니다.
#정리
- CXL.mem 지연은 토폴로지에 강하게 의존합니다 — Direct 178 ns, Switch 268 ns, Pool 412 ns.
- 대역폭은 *PCIe 이론값의 88%*가 sequential, *60%*가 random 수준입니다.
- NUMA remote DDR(142 ns)와 CXL Direct(178 ns)의 차이는 크지 않음 — NUMA 잘 다루는 워크로드는 CXL Direct에 잘 적응합니다.
- mlc·STREAM·DAMON이 measurement·sustained throughput·access pattern을 각각 측정하는 표준 도구입니다.
- 토폴로지 선택은 지연 budget이 결정합니다 — 200 ns 이내면 DDR, 400 ns OK면 Pool.
- Random access bandwidth가 60% 수준으로 떨어짐은 DRAM bank parallelism 깨짐 때문이며 access pattern 설계로 70% 이상 복구 가능합니다.
다음 편은 Ch 55: CXL 성능 프로파일링 도구 — cxl-cli·DAMON·perf-mem로 측정 환경 자체를 구축하는 법을 정리합니다.
#관련 항목
Embedded Performance Engineering · 55 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 처리량 회복
관련 글
메모리 대역폭 분석 — STREAM·Roofline·Bus Saturation 측정
STREAM benchmark (Copy·Scale·Add·Triad). Roofline. PMU BUS_ACCESS · DDR bandwidth.
실전 사례 — CXL.mem 추가로 LLM inference KV cache 처리량 회복
70B 모델 KV cache가 HBM 한계를 넘어 throughput이 무너졌을 때, CXL.mem 256 GB pool 추가로 회복한 실전 케이스.
CXL 성능 프로파일링 도구 — cxl-cli·DAMON·perf-mem 활용
CXL.mem 환경 성능 도구 — cxl-cli 토폴로지·DAMON page activity·perf-mem로 보는 CXL 트래픽·numastat 통계.
이 글을 참조하는 글 (9)
- 부트 시 메모리 토폴로지 결정 — DDR + CXL.mem 통합 인식— Bootloader Internals
- CXL 메모리 진단 — RAS·Poison List·Media Error 추적— Memory Diagnostics
- PCIe·CXL IDE 분석 — 링크 무결성과 데이터 암호화— Embedded Security
- 실전 사례 — CXL.mem 추가로 LLM inference KV cache 처리량 회복— Embedded Performance Engineering
- CXL 성능 프로파일링 도구 — cxl-cli·DAMON·perf-mem 활용— Embedded Performance Engineering
- 메모리 풀링과 데이터센터 토폴로지 — CXL Switch와 Fabric— HBM·GDDR 심화
- CXL.mem 프로토콜 분해 — M2S·S2M 메시지와 HDM Decoder— HBM·GDDR 심화
- Ch 15: RAS·Performance·Compliance — 운용·검증의 마지막 단계— CXL 4.0 Internals
- Ch 8: CXL.mem — M2S·S2M·HDM Decoder— CXL 4.0 Internals