第4章:性能测试指标——带宽、延迟、命中率与事务吞吐量

性能测试这件事,说白了就是拿数据说话。你做了缓存、优化了协议、调整了拓扑,效果怎么样?不能光靠“感觉快了”来交差。

我个人习惯先把四个核心指标摆出来:带宽、延迟、命中率和事务吞吐量。它们是 CXL.cache 性能的四个维度,缺一个都不完整。你想想看,光有高带宽但延迟爆炸,业务照样扛不住。四个指标之间相互制约,就像跷跷板——调了这边,那边就变了。

4.1 带宽——数据管道的“宽度”

带宽就是一秒能传多少数据。CXL.cache 走的是 PCIe 物理层,Gen5 x16 理论带宽大约 64 GB/s。但理论值永远到不了。我踩过最大的坑是拿理论值去预估业务,结果压测时带宽死活上不去。

注意:有效带宽受链路层开销、协议握手、重传机制影响。实测通常只有理论值的 70%~85%。

测带宽很简单:用 cxl list 确认设备后,跑 memcpy 或固定大小读写循环。看平均速率就行。我建议测三个点——小包(64B)、中包(1KB)、大包(64KB),因为不同大小下的带宽特性差很多。

4.2 延迟——那种“卡顿”的根源

延迟是比带宽更敏感的东西。CXL.cache 跨 die 访问时,每次 cache 缺失都得走一层甚至两层协议。我遇到过一种情况:命中率 99%,但用户还是觉得慢。查了半天,发现是 miss 后访问远端延迟太高——单次 miss 耗费 350ns,而本地只要 70ns。

测延迟工具:cxl latency 或者自己写 rdtsc 插桩。要特别注意两点:

  • 剔除 warmup 数据(前几百次不准)
  • 区分 local miss 和 remote miss 的延迟分布

我的经验:如果延迟 P99 和 P50 差距大于 30%,大概率是链路拥塞或调度抖动。这时候优先查中断亲和性和 NUMA 绑定。

4.3 命中率——缓存效果的“晴雨表”

命中率决定了大部分请求能不能在本地完成。90% 的命中率和 99% 的命中率,系统压力天差地别。为什么?因为 miss 后的代价是命中代价的 5~10 倍。

我曾在一次项目中看到命中率只有 78%,SSD 读写都被打满了。后来通过增加预取窗口和调整替换策略,命中率升到了 94%,延迟直接降了 40%。所以别只盯着带宽,命中率才是潜在大头。

测命中率注意采样粒度:

# 用 /sys/fs/cxl/cache_stat 定期读
while true; do
  cat /sys/fs/cxl/cache_stat | grep "hits\|misses"
  sleep 1
done

别只看整体命中率。我建议至少分读命中、写命中、预制命中三类统计,因为它们的延迟成本不一样。

4.4 事务吞吐量——真正扛压的能力

事务吞吐量(TPS)是压测场景下的关键指标。它把带宽、延迟、命中率都打包在一起:

TPS = 并发数 / 平均响应时间

但实际中,并发数到一定程度后延迟会急剧上升,TPS 出现拐点。这个拐点就是系统的极限吞吐。

核心概念:拐点之前叫线性区,之后叫饱和区。生产环境应该跑在 70%~80% 的线性区上限,别为了冒尖压到饱和区——抖一次你就知道疼了。

测 TPS 建议用 fio 加 --random 模式,或者使用开源的 cxl-load 工具。我曾见过团队只用 dd 测带宽,结果上线后 TPS 只有预期的一半……因为 dd 是顺序流,和真实随机访问完全两码事。

4.5 四个指标的关系——一张图说清楚

把这些关系画成图,你会看得更清楚。下面这张图我经常贴在工位旁边,每次调优前先扫一眼,心里就有谱了。

CXL.cache 性能指标关系图 带宽 GB/s 延迟 ns / μs 命中率 % 事务吞吐量 TPS 影响 & 被影响 带宽×命中率 → 有效吞吐;延迟加上 miss 代价 → 实际响应时间;四个指标要一起看,单点优化最坑人

4.6 实战:一次指标联合分析

讲个真实案例。某次我们做 CXL 内存池化,原型机跑 AI 推理。测下来带宽 48 GB/s(还不错),延迟 P50=125ns(还行),命中率 96%(有点低),TPSe 只有 21K。

我一看命中率 96% 还低?后来分析发现,推理模型有大量冷数据反复访问,命中率虽高但 miss 对延迟的惩罚巨大——每次 miss 要 400ns。把命中率提到 98.5% 后,TPS 直接翻到 58K。

不要只盯着一个指标。当时如果只优化带宽,可能白费力气。联合分析四个指标,才能定位到真正的瓶颈。

4.7 一键获取四个指标(工具推荐)

手工一个个测太慢。我自己写了个轻量脚本,收集关键信息:

#!/bin/bash
# cxl_perf.sh - 快速获取四个指标
echo "=== CXL.cache 性能快照 ==="
echo "带宽: $(cxl bandwidth --device all | awk '{print $4}') GB/s"
echo "延迟 P50: $(cxl latency --p50 | head -1) ns"
echo "命中率: $(cxl cache-stat --hit-ratio) %"
echo "TPS: $(cxl throughput --interval 1 | tail -1) ops/s"

这个脚本我放在 CI 里,每次新版本部署前跑一遍,异常值会自动告警。你想想看,有了自动化采集,再也不用半夜手动压测了。

4.8 注意点与避坑

  • 带宽测试前务必关闭 CPU 频率缩放和 Turbo Boost,否则数值忽高忽低。
  • 延迟测试要区分内核态和用户态路径——CXL 某些操作会陷入内核,延迟比用户态访问高一个数量级。
  • 命中率不能只看均值。我曾经遇到一个场景:白天命中率 98%,晚上业务切到另一批冷数据,命中率掉到 65%。要加时段监控。
  • TPS 测试时并发数建议从 1 开始逐渐增加,记录每步的响应时间。画一条“并发-TPS”曲线,拐点一目了然。

特别提醒:压测过程中如果发现四个指标同时异常抖动,先检查物理链路——CXL 线缆松动或 re-timer 温度过高会引发降速。别盲目去调参数。

四个指标我讲完了。记住一个原则:先测准,再调优。很多团队上来就改配置,结果连 baseline 都没建好,折腾半天也不知道有没有进步。先把带宽、延迟、命中率、TPS 的当前值记下来,作为新版本对比的起点。

嗯,数据不会骗人,但前提是你得会看数据。