2. PCIe基础概念

PCIe(Peripheral Component Interconnect Express)不是一条简单的并行总线,而是一套高速串行、点对点、全双工、分层协议的互连体系。理解它的架构与分层模型,是后续做吞吐测试、定位带宽瓶颈、分析链路错误的基础。很多测试工程师只关注“跑多少GB/s”,却忽略了数据从软件缓冲区到物理链路要经过事务层、数据链路层、物理层三次封装与两次解封装,任何一层的开销都会直接吃掉有效吞吐。

一、PCIe总线架构:点对点与交换结构

传统PCI是共享并行总线,多个设备争用同一组地址/数据线;PCIe则采用点对点链路,每个设备与上游端口之间是独立的双向链路。整个拓扑由三类核心部件构成:

  • Root Complex(RC,根复合体):CPU与PCIe世界的桥梁,负责发起配置、内存和I/O事务,通常集成在CPU或芯片组内。
  • Switch(交换器):由一个上游端口和多个下游端口组成,内部是虚拟PCI总线,实现多设备扩展与路由。
  • Endpoint(EP,端点):真正的功能设备,如NVMe SSD、网卡、GPU、FPGA加速卡。

链路以“Lane(通道)”为单位,常见x1、x4、x8、x16。每条Lane是独立的发送/接收差分对,因此PCIe天然全双工。吞吐测试中,x4 Gen4与x8 Gen3的理论带宽接近,但实际有效带宽受编码、TLP开销和协议层效率影响,不能只看Lane数。

二、分层模型:三层结构与各自职责

PCIe协议自顶向下分为事务层(Transaction Layer)、数据链路层(Data Link Layer)、物理层(Physical Layer)。发送方向逐层加头加尾,接收方向逐层剥离校验。下图展示了三层之间的封装关系与关键对象:

PCIe 三层封装与解封装示意 发送方向(封装) 事务层 TL 生成 TLP:Header + Data + ECRC 数据链路层 DLL 加 Sequence + LCRC,生成 DLLP 物理层 PHY 加 Framing,编码,串行发送 差分链路 Lane(全双工) 接收方向(解封装) 事务层 TL 解析 TLP,路由到目标功能 数据链路层 DLL 校验 LCRC,ACK/NAK 重传 物理层 PHY 时钟恢复,解码,去 Framing 关键对象: TLP = Header + Payload + ECRC;DLLP = Sequence + LCRC;PHY = Framing + 编码 + 电气信号 吞吐损耗点:TLP 头开销、DLLP 确认、ACK/NAK 重传、编码效率、链路训练与恢复

三、事务层:TLP 与事务类型

事务层是PCIe的“业务层”,负责把软件请求翻译成TLP(Transaction Layer Packet)。TLP由Header、可选Data Payload和可选ECRC组成。Header中携带Requester ID、Tag、地址/路由信息、流量类别TC、属性Attr等字段。

常见事务类型包括:

  • Memory Read / Write:最常用,用于访问MMIO和DMA缓冲区,吞吐测试主要压测对象。
  • Configuration Read / Write:枚举阶段访问配置空间,生成ECAM访问。
  • Completion:对Non-Posted请求的响应,带Completion Status和数据。
  • Message:用于中断(MSI/MSI-X)、电源管理、错误上报等。

事务层还负责流量控制(Flow Control),通过FC Credit机制避免接收端缓冲区溢出。发送端必须获得足够Credit才能发出TLP,因此Credit不足会直接限制吞吐。测试中若发现带宽远低于理论值,应优先检查FC Credit和Max Payload Size设置。

四、数据链路层:可靠传输与重传

数据链路层的核心使命是保证TLP在链路上可靠传输。它在TLP前后添加Sequence Number和LCRC,形成可校验的帧;同时生成DLLP用于ACK/NAK、电源管理和流控信用更新。

接收端校验LCRC,正确则回ACK,错误则回NAK,发送端重传对应TLP。这个机制保证了链路级可靠性,但重传会消耗带宽。误码率高的链路,吞吐会因频繁重传而明显下降。因此吞吐测试必须同时关注链路误码计数和重传次数。

提示:数据链路层的ACK/NAK是“累积确认”,一个ACK可以确认多个TLP。测试时若看到ACK密度异常,往往意味着接收端处理能力不足或缓冲区偏小。

五、物理层:编码、时钟与链路训练

物理层负责把数字比特流变成差分电信号,并完成链路训练。它包含逻辑物理层和电气物理层。逻辑部分完成Framing、加扰、编码;电气部分驱动发送器、接收器,进行时钟恢复和均衡。

编码方式随代际变化:Gen1/Gen2使用8b/10b,编码开销20%;Gen3及以上使用128b/130b,开销约1.5%;Gen6引入PAM4和FLIT模式。因此同样Lane数,Gen3的有效带宽远高于Gen2。

链路训练(LTSSM)包括Detect、Polling、Configuration、Recovery等状态。训练失败或降速会导致链路以更低Lane数或更低速率运行,吞吐自然下降。测试前应确认链路状态:

# 查看PCIe链路速率与宽度
lspci -vv -s 01:00.0 | grep -E "LnkCap|LnkSta"

# 典型输出
LnkCap: Port #0, Speed 16GT/s, Width x4
LnkSta: Speed 16GT/s, Width x4, TrErr- Train- SlotClk+ DLActive+

六、三层协作与吞吐测试关注点

三层不是孤立存在:事务层决定“发什么”,数据链路层决定“可靠地发”,物理层决定“以多快速度发”。吞吐测试的本质,是观察这三层在真实负载下的协同效率。

层次 关键对象 吞吐影响因素 测试观察点
事务层 TLP、FC Credit、Tag Payload大小、Credit不足、Tag耗尽 MaxPayload、FC状态、完成超时
数据链路层 DLLP、LCRC、Sequence 重传、ACK/NAK频率、缓冲区 重传计数、链路错误日志
物理层 Lane、编码、LTSSM 速率、宽度、误码、均衡 LnkSta、误码率、训练状态
常见误区:只看“理论带宽 = 速率 × Lane数 ÷ 编码开销”就判断吞吐是否达标。实际上,TLP头开销、DLLP确认、ACK/NAK重传、软件DMA效率都会进一步削减有效带宽。例如Gen4 x4理论约7.88GB/s,实际单向有效吞吐常在6.0~6.8GB/s之间,若低于5GB/s就应深入排查。

七、案例:一次吞吐不达标的复盘

某NVMe SSD在Gen4 x4平台上顺序读只有3.2GB/s,远低于预期。排查过程:

  1. 确认链路状态为Speed 16GT/s、Width x4,物理层正常。
  2. 检查MaxPayload,发现被设置为128字节,而设备支持512字节。
  3. 查看FC Credit,发现接收端Credit偏少,发送端频繁等待。
  4. 调整MaxPayload并重启后,吞吐提升到6.4GB/s。

这个案例说明:吞吐问题往往不在物理层,而在事务层的参数配置与流控机制。掌握三层模型,才能把“带宽不够”拆解成可验证的具体原因。

总结来看,PCIe总线架构提供了点对点全双工的基础,分层模型把复杂协议拆成事务层、数据链路层、物理层三个可独立观察的层次。做吞吐测试时,应沿着“物理层是否达标 → 数据链路层是否重传 → 事务层参数是否合理”的顺序逐层排查,而不是盲目更换硬件或反复跑分。