4. PCIe吞吐量定义

在PCIe性能测试中,最容易混淆的一组概念就是“带宽”和“吞吐量”。很多工程师在报告里写“PCIe 4.0 x16带宽是32 GB/s”,但实测只有25 GB/s左右,于是怀疑链路有问题。实际上,32 GB/s是理论带宽,25 GB/s才是实际吞吐量,两者之间的差距来自协议开销、编码方式、TLP包头、流控信用、DLLP/ACK等必要机制。理解这些概念,是后续做吞吐测试、定位瓶颈、判断结果是否合理的基础。

一、核心概念:从理论带宽到有效载荷

PCIe的“带宽”通常指链路的原始传输能力,由链路宽度(x1/x4/x8/x16)和每通道速率(2.5/5/8/16/32 GT/s)决定。注意单位是GT/s(每秒千兆传输),不是Gbps,因为PCIe采用8b/10b或128b/130b编码,传输符号数并不等于有效数据位数。

“吞吐量”指单位时间内真正成功传输的数据量,通常用GB/s或MB/s表示。它又分为两层:一层是链路层吞吐量,包含TLP包头和有效载荷;另一层是应用层有效吞吐量,只统计用户真正需要的数据,也就是有效载荷(Payload)。

“协议开销”是理论带宽和有效吞吐量之间的所有必要消耗,主要包括:

  • 物理层编码开销:Gen1/Gen2使用8b/10b,20%开销;Gen3及以上使用128b/130b,约1.54%开销。
  • TLP包头:Memory Read/Write TLP通常有12~16字节包头,加上ECRC可选4字节。
  • DLLP与ACK/NAK:链路层确认、流控信用更新、电源管理消息。
  • 物理层同步、SKP有序集、电气空闲等。
  • 事务层等待、信用限制、Tag数量限制导致的流水线空泡。
理论带宽 = 链路宽度 × 每通道速率 × 编码效率
链路层吞吐量 = 理论带宽 − 物理层/链路层开销
有效吞吐量 = 链路层吞吐量 − TLP包头/ECRC等事务层开销

二、理论带宽与实际吞吐量的关系图解

下图展示了从PCIe物理链路速率到应用有效载荷的逐层衰减过程。可以看到,Gen4 x16的理论带宽为32 GB/s,但经过编码、包头、流控和事务层开销后,实际有效载荷通常落在24~28 GB/s区间,具体取决于读写比例、TLP大小和访问模式。

PCIe Gen4 x16 从理论带宽到有效吞吐量的逐层衰减 ① 理论带宽(Raw Bandwidth) 16 lane × 16 GT/s × 128b/130b ≈ 32 GB/s(单向) 32 GB/s 扣除物理层编码与同步开销 ② 链路层吞吐量(Link Throughput) 包含TLP包头、DLLP、ACK/NAK、流控信用更新 ≈ 30 GB/s 扣除TLP包头、ECRC、事务层空泡 ③ 有效载荷吞吐量(Payload Throughput) 用户数据本身,不含任何协议头,是测试真正关心的指标 24~28 GB/s 受DMA效率、驱动、内存带宽、访问模式影响 ④ 应用层有效吞吐量(Application Goodput) 应用实际可用数据率,受软件栈、中断、拷贝次数影响 20~26 GB/s 关键结论 理论带宽是“上限”,有效吞吐量是“实测值”;两者差距由编码、包头、流控、软件栈共同决定。 测试报告必须明确标注:是链路层吞吐量,还是有效载荷吞吐量,否则数据无法横向对比。

三、理论带宽计算公式与常见参数

理论带宽的计算公式为:

理论带宽(GB/s) = 链路宽度 × 每通道速率(GT/s) × 编码效率 ÷ 8

Gen1 x1: 1 × 2.5 × 8/10 ÷ 8 = 0.25 GB/s
Gen2 x1: 1 × 5.0 × 8/10 ÷ 8 = 0.50 GB/s
Gen3 x1: 1 × 8.0 × 128/130 ÷ 8 ≈ 0.985 GB/s
Gen4 x1: 1 × 16.0 × 128/130 ÷ 8 ≈ 1.969 GB/s
Gen5 x1: 1 × 32.0 × 128/130 ÷ 8 ≈ 3.938 GB/s

以Gen4 x16为例:16 × 16 × 128/130 ÷ 8 ≈ 31.5 GB/s,工程上常近似为32 GB/s。但这是单向理论值,双向同时传输时总带宽共享,实际单向吞吐量还会受方向切换和流控影响。

层级 统计对象 Gen4 x16典型值 测试工具示例
理论带宽 物理链路原始速率 ≈32 GB/s 公式计算
链路层吞吐量 TLP+DLLP+物理层有效符号 ≈30 GB/s 协议分析仪
有效载荷吞吐量 TLP Payload 24~28 GB/s CUDA bandwidthTest、iperf3
应用层有效吞吐量 应用可用数据 20~26 GB/s fio、dd、自定义DMA程序

四、案例:为什么实测只有理论值的70%

某服务器使用Gen4 x16 SSD,厂商标称顺序读7 GB/s,但用户用fio测试只有5.2 GB/s。排查后发现:

  1. fio默认块大小4KB,TLP包头占比高,有效载荷效率下降。
  2. 未开启NVMe多队列,中断集中在CPU0,DMA提交存在空泡。
  3. 文件系统未使用O_DIRECT,数据经过页缓存多拷贝一次。
  4. 测试时链路实际协商为Gen4 x8,理论带宽减半。

调整后使用128KB块大小、O_DIRECT、多队列,实测达到6.6 GB/s,约为理论值的82%,属于合理范围。这说明:吞吐量测试必须同时记录链路状态、块大小、队列深度和软件路径。

测试前先确认链路协商结果:
lspci -vv -s 01:00.0 | grep -i "LnkSta"
输出中“Speed 16GT/s, Width x16”才代表Gen4 x16已正确协商。

五、常见误区与复盘

  • 误区一:把GT/s当GB/s。 Gen4 x16是16 GT/s,不是16 GB/s,必须除以8并乘编码效率。
  • 误区二:忽略方向。 理论带宽通常指单向,双向测试要分别统计或明确标注。
  • 误区三:用应用层吞吐量对比链路层指标。 两者统计口径不同,不能直接比较。
  • 误区四:认为开销是“浪费”。 编码、包头、ACK、流控是PCIe可靠传输的必要机制,不是设计缺陷。
  • 误区五:只看峰值不看稳定性。 吞吐量测试应关注持续带宽、抖动和CPU占用率。
在写测试报告时,必须注明:链路速率、链路宽度、TLP大小、读写方向、测试工具、是否经过文件系统、CPU占用率。缺少这些信息,吞吐量数字没有可比性。

总结来说,理论带宽是PCIe链路的物理上限,吞吐量是实际传输能力,有效载荷是用户真正获得的数据。协议开销决定了二者之间的差距,而测试方法决定了你测到的是哪一层。只有把这几层概念分清,后续的吞吐测试、瓶颈定位和性能优化才有可靠的基准。