본문으로 건너뛰기
CXL 4.0 Internals · 7/15

Ch 7: CXL.cache — D2H·H2D 흐름과 coherency state

· Hawk · 9분 읽기

#한 줄 요약

“CXL.cache는 디바이스가 host 메모리를 native 캐시하게 만들어 PCIe 라운드트립을 회피하는 프로토콜입니다.”D2H Req (device → host: read·write·invalidate)와 H2D Snoop·Resp·DataMESI 기반의 양방향 cache coherency를 유지합니다. Type 1·2 디바이스가 사용하며, Type 1 SmartNIC의 packet metadata 캐싱이 대표적 사용 사례입니다.

Ch 6에서 CXL.io의 PCIe 호환성을 봤습니다. 이 장은 디바이스가 host memory를 native 접근하는 CXL.cache 메커니즘입니다. PCIe DMA의 한계를 넘는 coherent caching이 핵심입니다.

#왜 CXL.cache가 필요한가

기존 PCIe 가속기는 host RAM 접근DMA로만 합니다. 문제:

  • Round-trip 비용 — 매 access마다 DMA setup·완료
  • No caching — 같은 데이터 반복 access도 매번 DMA
  • No coherency — host가 cache한 데이터를 device가 못 봄

CXL.cache는 디바이스에 작은 local cache를 두고 host memory의 hot regioncoherent하게 캐시합니다.

시나리오PCIe DMACXL.cache
같은 데이터 반복 read매번 DMA (느림)첫 read 후 cache hit (빠름)
Coherency없음 (app가 처리)자동 (hardware)
Latency수 µs (DMA)수십 ns (cache hit)

#CXL.cache 메시지 — D2H·H2D

CXL.cache는 양방향 메시지로 동작합니다.

방향채널메시지 종류의미
Device → HostD2H ReqRdShared·RdOwn·RdAny·CLflushed·Invalidate·…device가 read·write·invalidate 요청
Device → HostD2H Resp·Dataresponse·data returnhost snoop 응답·data 반환
Host → DeviceH2D Req·Snoopsnoop·invalidatehost가 device cache 동기화
Host → DeviceH2D Resp·Dataresponse·data returndevice read 응답·data 반환

양방향 모두 Req·Resp·Data 3가지 트래픽. PCIe DMA보다 훨씬 정교한 메시지 set입니다.

#Read 흐름 — Device가 Host 메모리 Read

가장 단순한 D2H read:

단계동작
1Device가 cache miss 발생 — addr=X
2Device → Host: D2H Req RdShared, addr=X
3Host CPU의 cache line 상태 확인
4Host → Device: H2D Resp + H2D Data (64 B)
5Device cache에 line 채움, state = Shared
6Device 내부 use

RdShared읽기 전용 사본. 만약 device가 write 의도RdOwn (exclusive 요청). RdOwn은 host의 다른 sharer를 invalidate.

#Write 흐름 — Device가 Host 메모리 Write

단계동작
1Device가 cache line modify 의도
2Device → Host: D2H Req RdOwn, addr=X (exclusive 요청)
3Host CPU의 cache에서 다른 sharer invalidate
4Host → Device: H2D Resp + H2D Data (line 보냄)
5Device cache에 line 채움, state = Modified
6Device가 modify, 캐시에 보관
7Eviction 또는 explicit writeback 시 → host로 반환

#Snoop 흐름 — Host CPU가 같은 Line Read

Device cache에 modified line이 있는데 host CPU가 같은 line read하면:

단계동작
1Host CPU read miss — addr=X (이미 device가 Modified state)
2Host → Device: H2D Snoop SnpData, addr=X
3Device cache 확인 — Modified line 있음
4Device → Host: D2H Resp + D2H Data (modified data 반환)
5Device cache state → Shared (또는 Invalid)
6Host CPU가 fresh data 받음

이 흐름이 MESI coherency의 핵심. Device·Host 양쪽 cache가 같은 line을 가질 때 coherency 유지.

#Cache State — MESI 변형

CXL.cache는 MESI (Modified·Exclusive·Shared·Invalid)와 그 변형을 지원합니다.

State의미Device에서
Modified (M)exclusive + dirtydevice가 유일 소유, host RAM과 다름
Exclusive (E)exclusive + cleandevice가 유일 소유, host RAM과 동일
Shared (S)shared + cleandevice·host(들)이 공유 read
Invalid (I)line 없음cache eviction 또는 invalidate된 상태

추가 state:

State의미
Forward (F)shared 중 forwarding 책임 갖는 sharer (4-state 변형)
Owned (O)shared but dirty (MOESI 변형)

어떤 state set지원하는지디바이스 capability에 따라 다릅니다. 보통 MESI가 최소 baseline.

#Type 1 시나리오 — SmartNIC Packet Metadata

대표적 production sweet spot:

시나리오동작
1NIC가 packet 받음, packet header 검사 필요
2Packet metadata는 host RAM에 있음 (routing table·flow state)
3NIC가 D2H RdShared로 metadata read
4NIC cache에 저장, state = Shared
5다음 packet도 같은 metadata 사용 → cache hit, host 접근 없음
6Host CPU가 routing table update 시 H2D Snoop SnpInv로 NIC cache invalidate
7NIC가 다음 packet에 RdShared로 fresh data fetch

이 패턴이 NIC packet processing throughput수십% 향상시킬 수 있습니다 (workload 의존).

#Type 2 시나리오 — Accelerator의 Shared Data

Type 2 GPU·NPU도 CXL.cache를 사용해 host의 shared data에 접근합니다.

시나리오동작
LLM weighthost에 보관, GPU가 부분 read·캐시
Tokenization tablehost에 보관, GPU·NPU가 read
Configurationhost control plane, GPU가 cache

Type 2는 자체 HBM이 있어 대부분의 hot data는 자기 HBM. CXL.cache는 간헐적으로 필요한 host data효율적으로 접근하는 데 활용.

#False Sharing — 최악 시나리오

같은 cache line의 다른 bytedevice와 host가 번갈아 modify하면 cache ping-pong 발생:

시간DeviceHost CPU트래픽
t1byte 0 modifyD2H RdOwn, line snatched
t2byte 32 modifyH2D Snoop, line snatched back
t3byte 0 againD2H RdOwn again
(반복)(반복)매번 BISnp 트래픽

throughput이 무너집니다. 해결:

  • Cache line padding — 다른 byte를 별도 line으로 분리
  • alignas(64) — 구조체 alignment 명시
  • 데이터 layout 재설계AoS vs SoA 선택

#Linux 측 — CXL.cache 활용

Type 1 디바이스의 CXL.cache는 vendor driver 내부에서 사용. 별도 sysfs 노출 없음.

Terminal window
# Type 1 NIC가 attach되면 lspci에 보이지만
$ lspci -nn | grep -i smartnic
5e:00.0 Ethernet controller [0200]: ... [...]
# CXL.cache 자체는 sysfs에 노출 안 됨
$ ls /sys/bus/cxl/devices/
# (Type 1만 있으면 빈 디렉토리)
# vendor 드라이버 내부에서 cache 기능 사용
$ dmesg | grep -i "cxl.cache"
nic0: CXL.cache enabled, cache size 8 MB

Type 2의 CXL.cache는 coro·CUDA 같은 high-level runtimebias·access pattern hint를 제공.

#자주 하는 실수

#”CXL.cache가 있으면 무조건 빠르다”

Cache hit rate가 충분해야 합니다. 불규칙한 access patterncache miss → DMA-like round-trip. 워크로드 temporal locality 분석 필수.

#”Cache line padding은 불필요하다”

CXL.cache 환경에서는 false sharing이 매우 비쌉니다. modern C++의 std::hardware_destructive_interference_size 사용 권장.

#”Device cache state는 software가 관리”

Hardware가 자동 관리합니다. software는 bias hint·prefetch 같은 hint만 줄 수 있고 state transition은 hardware가 결정.

#”MESI면 모든 CXL 디바이스가 호환”

State set이 디바이스마다 다를 수 있음. MESI·MOESI·MESIF 변형들. capability 확인 필요. CXL.io DVSEC에서 지원 state 표기.

#”Snoop overhead가 항상 무시 가능”

High-contention shared data에서는 snoop 트래픽이 dominant가 됩니다. Type 2 GPU의 shared weight scan에서 snoop 비용이 compute보다 큰 워크로드도 존재.

#정리

  • CXL.cache는 디바이스가 host memory를 native cache하는 프로토콜입니다.
  • D2H·H2D 메시지MESI coherency를 양방향 유지. PCIe DMA보다 정교한 메시지 set.
  • Read는 RdShared/RdOwn, Write는 RdOwn → Modified, Host의 update는 Snoop으로 device cache invalidate.
  • Type 1 SmartNIC의 packet metadata 캐싱이 가장 명확한 production fit.
  • False sharing최악 시나리오 — cache line padding으로 회피.

#다음 편

Ch 8: CXL.mem — M2S·S2M·HDM Decoder에서 host가 device memory에 load/store하는 CXL.mem 프로토콜의 메시지 흐름HDM Decoder의 주소 매핑을 본격적으로 분해합니다.

#관련 항목

#시리즈 자료 출처 안내

본 글은 CXL Consortium·Linux drivers/cxl/ 소스·academic 연구를 1차 자료로 합니다. CXL 4.0 Specification은 § navigation aid로만 인용. 자세한 spec 인용 정책은 Ch 1 footer 참고.