← 全部文章

为什么我的第一次 CPU 基准测试噪声太大无法使用,以及我如何修复

2026年11月5日

我最初的基准测试数字看起来还算合理,直到我把同样的测试跑了两次,得到了不同的结果。这篇文章讲的是我如何找出原因,以及在相信任何数字之前我改了什么。

所有数字都来自 cpu-inference-bench 仓库的 README(包括其中的 “First attempt (archived)” 部分)和 results/archive_summary.json。

第一次尝试是无效的

我一开始在笔记本 CPU(Intel i7-12650H)上,用默认设置在 PyTorch、ONNX Runtime 和 OpenVINO 上运行 ResNet-18。为了检查可重复性,我把每个配置都运行了两次。在 18 组重复测量中,有 12 组两次相同运行之间的差异超过 5%,其中一组(PyTorch,12 线程,batch 1)最高达 48.27%。这些结果无法用于比较,所以我把它们归档了。

笔记本有封装功耗和温度限制,所以频率会在运行过程中变化。如果不控制这一点,框架之间几个百分点的差异就在噪声范围内。

寻找原因

第一次尝试使用默认的频率调节,所以频率可以自由变化。这颗 CPU 的持续封装功耗限制为 45 W,短时限制为 115 W,这类功耗和温度限制都可能在运行过程中改变频率。后台服务和共用这些核心的其他进程也可能带来噪声。

那次尝试的数据只存档在本地,不在公开仓库中,所以我无法在这里展示每次运行的频率或温度。我没有去猜哪个因素占主导,而是改了测试环境,让每个因素要么被控制,要么可见:现在每次重复都会记录封装温度、P 核的平均和最低频率,以及内核的热降频计数器。

一次仍然不够的试运行

我把 P 核频率上限设为 3000 MHz,并做了一次小规模试运行。四组中仍有两组触发了内核的热降频计数器,所以我选择了 2600 MHz,这是核心能够持续维持的频率。

我改了什么

所有报告的运行都使用:

  • 6 个 P 核固定在 2600 MHz,SMT 兄弟线程离线,这是核心能够持续维持的频率,而不是峰值频率;
  • 绑定核心、接通交流电源并停止后台服务;
  • 每次重复前等待冷却,直到封装温度低于 60 °C;
  • 交错轮次,这样漂移对所有框架的影响相同;
  • 稳定性规则:只有 5 次重复的波动低于 5% 且没有任何热降频计数器增加时,该组才算稳定。

只在两个稳定的组之间给出加速比。不稳定的组会被显示并标记,而不是被丢弃。

这给了我什么

在这些控制下,ResNet-18 在 batch 1 下 INT8 对 FP32 的加速比为:PyTorch 2.34×,ONNX Runtime 2.74×,OpenVINO 3.48×(2.6 ms)。36 组 BERT 数据中有 5 组,以及 ResNet-18 的 18 组中有 2 组(均为 FP32 组)仍然不稳定,README 中也如实说明了这一点。

它没有说明什么

热降频计数器无法检测功耗限制导致的降频,所以我还检查了频率列。所有运行期间都开着一个 VPN 客户端,我没有测量它的影响。这只是一台笔记本和一次测试。

我的收获

  • 在比较任何东西之前,先把同一配置运行两次。
  • 如实报告不稳定的结果,不要隐藏。
  • 写下你没有控制的因素(这里是:功耗限制、VPN)。

代码由 Claude Code 编写;方法、决策与验证由我完成。