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

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

· Hawk · 9분 읽기
cxl-cache d2h h2d mesi snoop

#한 줄 요약

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

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 region을 coherent하게 캐시합니다.

시나리오PCIe DMACXL.cache
같은 데이터 반복 read매번 DMA첫 read 후 디바이스 cache hit
Coherency소프트웨어가 처리하드웨어가 처리

#CXL.cache 메시지 — D2H·H2D

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

방향채널메시지 종류의미
Device → HostD2H ReqRdCurr·RdShared·RdOwn·RdAny·RdOwnNoData·ItoMWr·WrCur·WrInv·CLFlush·CleanEvict·DirtyEvict·CacheFlushed 등device가 read·write·eviction 요청
Device → HostD2H Resp·Dataresponse·data returnhost snoop 응답·data 반환
Host → DeviceH2D ReqSnpData·SnpInv·SnpCurhost가 device cache를 snoop
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)를 씁니다. host는 응답(GO)에 4-bit MESI 인코딩을 실어 디바이스가 그 line을 어떤 상태로 가져도 되는지 알려 줍니다.

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된 상태

#Type 1 시나리오 — 반복해서 읽는 host 데이터

CXL 1.1 규격이 드는 Type 1의 예는 복잡한 atomic 연산이 필요한 가속기입니다. 더 일반적으로는, host 메모리에 있는 작고 자주 읽는 데이터를 디바이스가 캐시하는 흐름이 CXL.cache의 기본 모양입니다.

단계동작
1디바이스가 host 메모리의 데이터를 RdShared로 읽음
2디바이스 cache에 저장, state = Shared
3같은 데이터를 다시 쓰면 cache hit, host 접근 없음
4host CPU가 그 데이터를 바꾸면 SnpInv로 디바이스 cache를 무효화
5디바이스가 다음 접근 때 다시 RdShared로 가져옴

#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의 다른 byte를 device와 host가 번갈아 modify하면 cache ping-pong 발생:

시간DeviceHost CPU트래픽
t1byte 0 modify—D2H RdOwn, line snatched
t2—byte 32 modifyH2D Snoop, line snatched back
t3byte 0 again—D2H RdOwn again
…(반복)(반복)매번 D2H 요청과 H2D snoop

throughput이 무너집니다. 해결:

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

#Linux 측 — CXL.cache 활용

Type 1 디바이스는 HDM이 없어 /sys/bus/cxl/devices/ 아래 CXL 메모리 장치로 등장하지 않습니다. 디바이스가 CXL.cache를 지원하는지는 CXL DVSEC의 capability로 보입니다.

Terminal window
$ lspci -vvv -s 5e:00.0
Capabilities: [...] Designated Vendor-Specific: Vendor=1e98 ID=0000 Rev=1 Len=56: CXL
CXLCap: Cache+ IO+ Mem- ...

#자주 하는 실수

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

Cache hit rate가 충분해야 합니다. 불규칙한 access pattern은 cache 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가 관리합니다. 디바이스가 가질 수 있는 상태는 host가 GO 응답의 MESI 인코딩으로 정합니다.

#“CXL.cache 디바이스는 MOESI·MESIF 상태도 쓴다”

CXL 규격이 정의한 디바이스 캐시 상태는 MESI입니다. Owned·Forward 상태는 규격에 없습니다.

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

host와 디바이스가 같은 line을 자주 번갈아 쓰면 snoop 트래픽이 커집니다. 공유 데이터의 배치와 access pattern을 먼저 봐야 합니다.

#정리

  • 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.
  • 디바이스 캐시 상태는 MESI이고, host가 GO 응답으로 허용 상태를 정합니다.
  • False sharing이 최악 시나리오 — cache line padding으로 회피.

#다음 편

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

#관련 항목

#시리즈 자료 출처 안내

이 글은 CXL 3.1·1.1 spec를 근거로 합니다. 시리즈 전체의 자료 정책은 Ch 1에 있습니다.