1. CXL 技术简介:背景、动机与 PCIe 的关系

1.1 为什么需要 CXL?

这几年数据中心越来越难搞了。CPU 核数堆到上百,内存带宽还是跟不上。AI 加速器、FPGA、SmartNIC 这些设备都想直接访问主机内存,但传统 PCIe 只能做点对点 DMA,缓存一致性基本没有。

我记得 2019 年帮一个客户搭异构计算平台,CPU 和 GPU 之间靠 PCIe 搬数据,每次搬完还要强制刷新缓存,延迟高得离谱。客户问:能不能让 GPU 直接看到 CPU 的内存?当时我只能摇头——PCIe 没这能力。

所以 CXL(Compute Express Link)来了。它不是什么全新总线,而是基于 PCIe 物理层,在上层加了缓存一致性、内存语义和更灵活的协议。说白了,CXL 让 CPU、内存、加速器可以共享一份一致的内存视图。

核心动机:解决异构计算中内存访问不连续、缓存不一致、延迟过高的问题。

1.2 动机——从 PCIe 的痛点说起

PCIe 经历过很多代,从 Gen1 到 Gen5,带宽翻了很多倍。但它的设计初衷是“外设互联”,不是“一致性内存互联”。痛点很明显:

  • 无缓存一致性:设备写内存后,CPU 缓存可能还是旧数据,必须靠软件做 cache flush。
  • 内存语义缺失:PCIe 只有 load/store 和 DMA,没有直接的内存分配/共享语义。
  • 延迟不可控:PCIe 事务层需要复杂的封装和解封装,往返延迟动不动就几百纳秒。

我在做 FPGA 加速卡项目时踩过一个大坑:FPGA 通过 DMA 把结果写到主机内存,CPU 侧的应用程序读到的数据偶尔是错的。查了两天,最后发现是 cache coherence 问题。从那以后,我就在想:如果有一个原生支持一致性的总线该多好。

CXL 的动机就是填这个坑。它保留了 PCIe 的物理层优势(高速、成熟、可扩展),同时定义了三种子协议,分别覆盖 I/O、缓存和内存操作。

1.3 CXL 与 PCIe 的复用关系

很多人问我:CXL 和 PCIe 到底是什么关系?是替代还是共存?

我的回答很直接:CXL 寄生在 PCIe 上。它完全复用了 PCIe 的 PHY(物理层)、电气层、链路训练和部分数据链路层。说白了,CXL 的设备插到 PCIe 插槽里就能跑,因为底层的 SerDes、时钟恢复、均衡都是通用的。

但 CXL 在事务层做了自己的扩展,加入了缓存一致性协议和内存协议。你可以把 PCIe 理解成高速公路,CXL 就是在这条高速上跑的“特快车”,它有自己专用的交通规则。

PCIe 与 CXL 层级复用对比
层级PCIeCXL
物理层 (PHY)Gen1-Gen6 SerDes完全复用
数据链路层 (DLL)ACK/NAK, CRC, 重传复用基础结构,增加 CXL 特定的重传机制
事务层 (TL)Memory/IO/Config 事务CXL.io 保留 PCIe 事务;CXL.cache 和 CXL.mem 是全新协议
协议层无三种子协议:io / cache / mem

注意,CXL.cache 和 CXL.mem 不依赖于 PCIe 的事务层,它们是直接在数据链路层上构建的。这也是为什么 CXL 设备需要专门的控制器,不能简单用普通 PCIe 控制器驱动。

避坑点:我曾经在设计 CXL 端点时,以为直接拿 PCIe IP 改一下就能用。结果发现链路训练完成后,CXL 需要额外的 flit 格式协商,普通 PCIe 控制器根本不支持。所以复用物理层没错,但上层逻辑必须重新设计。

1.4 一张图看懂 CXL 与 PCIe 的关系

下面这张分层图可以帮你理清思路。底层是 PCIe 物理层,中间是 PCIe 数据链路层(部分复用),最上层是 CXL 的三个子协议。

CXL与PCIe分层结构 PCIe 物理层 (PHY) — SerDes, 链路训练, 均衡 PCIe 数据链路层 — ACK/NAK, CRC, flit 封装 CXL.io 发现/枚举/配置 CXL.cache 缓存一致性 / 探测过滤 CXL.mem 内存语义 / 共享访问 CXL 协议栈完全复用 PCIe PHY 和部分 DLL 三个子协议共享同一个物理连接 CXL.cache 和 CXL.mem 需要专用控制器

1.5 CXL 的三种子协议

了解复用关系后,必须搞懂三个子协议的分工:

  • CXL.io:负责设备发现、配置、中断、DMA 等传统 PCIe 功能。你的 CXL 设备首先要通过 CXL.io 枚举出来,然后才能协商是否启用 cache 和 mem 能力。
  • CXL.cache:让设备(比如加速器)可以缓存主机内存中的数据,并且保持一致性。设备端可以发起 snoop 请求,主机端会回传最新数据。这条协议对延迟极其敏感,所以 flit 设计非常紧凑。
  • CXL.mem:把主机内存直接暴露给设备,设备可以像访问本地内存一样 load/store。典型应用是内存池化(Memory Pooling)和内存扩展。

一个设备可以选择只实现 CXL.io,或者同时实现 CXL.io + CXL.cache,或者 CXL.io + CXL.mem。全栈实现很少见,因为成本高。

重要提醒:CXL.io 和 PCIe 的事务层不兼容!虽然 CXL.io 复用了 PCIe 的物理层,但其 flit 格式和事务编码都做了修改。普通 PCIe 交换机无法转发 CXL.io 流量,必须使用支持 CXL 的交换机。

1.6 回头看:CXL 为什么成功?

我个人的观点:CXL 最聪明的地方就是不重新发明轮子。它直接站在 PCIe 的肩膀上,省去了几十亿美元的物理层研发费用。你想想看,如果是全新的 SerDes、全新的连接器、全新的电气标准,那要花多少年才能普及?

CXL 联盟(Intel、AMD、Google、Microsoft 等)选择复用 PCIe 物理层,让生态可以平滑过渡。现在主流 CPU 厂商都在集成 CXL 控制器,这速度比任何新总线都快。

但也要记住:复用不等于一模一样。CXL 在链路层增加了 flit 模式训练,在事务层增加了缓存一致性协议,这些改动让实现复杂度上了一个台阶。后面几章我会详细拆解物理层的复用细节,包括到底哪些寄存器和状态机是共享的,哪些需要自己实现。