Exercises — CXL (Compute Express Link)
Before we start, one picture fixes every term used below. Look at it whenever you feel lost.

The host is the CPU. An accelerator is a GPU/FPGA that can cache host memory (that is CXL.cache). A memory device is a box of RAM the CPU reaches over the wire (that is CXL.mem). The three arrows are the three sub-protocols riding one PCIe cable.
Level 1 — Recognition
Exercise 1.1 — Match the protocol
For each need below, name which of the three CXL sub-protocols (CXL.io, CXL.cache, CXL.mem) does the job.
(a) A legacy driver must enumerate the device with plain PCIe config reads. (b) A GPU wants to hold a coherent copy of a CPU cache line. (c) The OS wants to see a plug-in RAM box as extra system memory.
Recall Solution
(a) CXL.io — this is ordinary PCIe (config, MMIO, DMA). Every CXL device must support it so it boots in non-CXL slots. (b) CXL.cache — the accelerator caches host memory and joins the coherency protocol. (c) CXL.mem — the host reaches device memory as part of its physical address space.
Direction is the tell: .cache = device caching host's RAM; .mem = host reaching device's RAM.
Exercise 1.2 — MESI state naming
A cache line held by the CPU is dirty (its value differs from main memory), and the accelerator's copy is absent. Name both states.
Recall Solution
CPU = Modified (M): it has the only up-to-date, dirty copy, so it must write back before anyone else reads. Accelerator = Invalid (I): it has no valid copy. This is exactly the row "Modified | Has dirty data | Invalid | CPU only" from the parent table.
Level 2 — Application
Exercise 2.1 — Per-lane bandwidth from raw rate
PCIe 5.0 runs at (giga-transfers per second) per lane and uses 128b/130b encoding — for every 130 bits on the wire, only 128 carry your data (2 bits are overhead). Compute the effective data rate per lane in , then convert to (8 bits = 1 byte).
Recall Solution
What we do: scale the raw rate by the useful fraction of bits. Why: each transfer moves 1 bit on the wire, but only of those bits are your payload. Convert to bytes (divide by 8): This matches the parent note's per lane.
Exercise 2.2 — Scale to a ×16 link
A CXL 1.0 link is (16 lanes) and is full-duplex (same rate each direction simultaneously). Give (a) one-direction bandwidth and (b) the aggregate bidirectional figure.
Recall Solution
(a) One direction: multiply per-lane by 16. Hmm — the parent quotes 32 GB/s each direction. The difference is because the parent rounds the usable protocol rate down (framing/flit overhead on top of encoding) to a clean "". So: (b) Aggregate = ==== bidirectional, i.e. each way in practice.
Two numbers, two meanings: is the encoding-only ceiling; () is the rounded protocol figure the spec advertises. Both appear in the parent — they are not contradictions.
Level 3 — Analysis
Exercise 3.1 — Trace a coherent read
The CPU holds line at address A in Modified state (dirty). The GPU issues ReadShared(A). Write the exact ordered steps and give the final MESI state of both caches. Explain why the write-back must happen.
Recall Solution
Follow the arrows in the figure below.

- GPU sends
ReadShared(A)across CXL.cache to the host. - Host snoops its own cache, finds
Ain Modified → it holds the only correct value. - Host writes back the dirty line to main memory. Why: memory currently holds a stale value; if we skipped this, a later reader that goes straight to memory would see garbage. Coherency requires memory to hold the truth once the line is Shared.
- Host sends the fresh data to the GPU and downgrades its own copy M → Shared.
- GPU installs the line in Shared. Final states: CPU = Shared, GPU = Shared. Neither may write now without first requesting ownership.
Exercise 3.2 — Why not just let both write?
State the single-writer / multiple-reader invariant and explain, using Exercise 3.1's line, what breaks if the GPU were allowed to write while the CPU stayed Modified.
Recall Solution
Invariant: at any instant a cache line has either one writer (Modified/Exclusive) or any number of readers (Shared) — never a writer plus another accessor.
If the CPU stayed Modified (writing A = 5) while the GPU also wrote (A = 9), there are now two divergent "truths." A later reader could see 5 or 9 depending on which cache it snooped — the classic incoherency the parent's Google-Docs analogy warns about. The downgrade to Shared enforces exactly one authoritative value.
This is the same coherency discipline described in Cache-CoherencyProtocols.
Level 4 — Synthesis
Exercise 4.1 — Memory expansion budget
An 8-socket server has DRAM per socket. An in-memory database needs . You add CXL memory expanders of each over CXL.mem. (a) How much DRAM is on-board? (b) How many expanders are needed? (c) What total address-space size does the OS see?
Recall Solution
(a) On-board DRAM . (b) Shortfall ; each expander is , so expanders. (c) OS sees of unified physical address space. The CPU's memory controller checks each physical address: if it falls in DRAM range it issues a DDR command; if beyond, it formats a CXL.mem transaction and routes to the expander. This tiering idea underlies NUMA-(Non-Uniform-Memory-Access) — near memory is fast, CXL memory is a farther "NUMA node".
Exercise 4.2 — Latency-aware access mix
Local DRAM latency ; CXL memory latency . A workload makes of its accesses to hot data in DRAM and to warm data in CXL memory. Compute the average access latency. Then compare against an all-DRAM ideal.
Recall Solution
Why a weighted average: each access pays the latency of wherever its data lives; the expected latency is the probability-weighted sum. All-DRAM ideal would be , so the CXL tier costs () extra latency — but buys you memory capacity you physically could not fit in DIMM slots. Compare with NVMe at tens of microseconds: CXL memory is still faster than flash.
Level 5 — Mastery
Exercise 5.1 — Model-serving capacity
A 70B-parameter language model stored in fp16 ( bytes per parameter) must be served. GPU VRAM . (a) Model weight size? (b) Does it fit in one GPU? (c) With a CXL memory expander, does it fit, and what protocol streams weights to the GPU?
Recall Solution
(a) .
(b) → no, it does not fit in one GPU's VRAM.
(c) → yes, it fits in the CXL expander. The GPU issues ReadShared(weight_addr) over CXL.cache; the CXL controller fetches 64-byte cache lines from expander memory on demand and the GPU caches them coherently for the current layer. This replaces slow manual copies with coherent on-demand streaming (contrast DMA-(Direct-Memory-Access), which copies blocks without coherency).
Exercise 5.2 — Bandwidth ceiling on weight streaming
Suppose each token's forward pass must touch all of weights once, streamed over a CXL 3.0 link at per direction. (a) Minimum time per token from bandwidth alone. (b) Peak tokens/second this ceiling allows.
Recall Solution
(a) Why divide bytes by bandwidth: time to move bytes over a link of rate bytes/s is . (b) Tokens/s . Interpretation: streaming every weight per token is brutally slow — this is why real systems keep hot weights resident in VRAM (HBM-(High-Bandwidth-Memory) gives TB/s) and use CXL memory as an overflow tier, not the primary path. The exercise reveals why HBM exists alongside CXL: bandwidth, not capacity, is the bottleneck for hot weights.
Exercise 5.3 — Generation reasoning
CXL 3.0 adds peer-to-peer device-to-device transfers over a fabric, "like NVLink but open." Explain in two sentences why removing the CPU from a GPU→GPU transfer matters, and name the earlier open interconnects CXL absorbed.
Recall Solution
Removing the CPU eliminates a round-trip through host memory and the CPU's coherency engine, so GPU→GPU data moves directly across the fabric at fabric speed with lower latency and no host-bandwidth tax. The earlier efforts CXL effectively subsumed are Gen-Z-and-CCIX — their memory-semantic and coherency ideas were folded into the CXL 2.0/3.0 fabric model.
Recall One-line self-test recap
.cache = device caches host RAM; .mem = host reaches device RAM ::: right
PCIe 5.0 per-lane effective rate ::: ~3.94 GB/s
CXL 1.0 x16 aggregate ::: 64 GB/s (32+32)
Read of a Modified line ends in state ::: Shared for both
70B fp16 model size ::: 140 GB
Invariant CXL enforces ::: single-writer or multiple-reader