ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

降低微基准测试方差:Google Benchmark 的 CPU 调频检测、锁频与执行环境优化实战

降低微基准测试方差:Google Benchmark 的 CPU 调频检测、锁频与执行环境优化实战 性能测试【免费下载链接】benchmarkA microbenchmark support library项目地址https://gitcode.com/gh_mirrors/benchmark5/benchmark点击查看免费下载微基准测试的价值取决于结果的可重复性而一次性的快慢往往只是噪声。本文基于 docs/reducing_variance.md 展开讲解 benchmark 库在启动时如何检测并警告 CPU 频率调频CPU Frequency Scaling如何关闭调频与处理器加速Boost以及如何通过任务亲和、关闭 SMT、收敛工作集等手段系统性地压降单次运行与多次运行之间的方差并结合src/下的源码说明--benchmark_repetitions重复测量与 mean/median/stddev 统计聚合的实现原理。读完本文你能够配置一套低噪声基准测试环境并正确解读 benchmark 输出中由重复测量产生的聚合统计结果。一、从警告信息说起benchmark 如何检测 CPU 调频当你运行一个 benchmark 程序时如果看到如下输出***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.这表示系统启用了 CPU 频率调频。在调频状态下CPU 会随负载动态升频/降频实测耗时real time measurement因此变得嘈杂noisy且调频机制本身还会引入额外开销。此时建议关闭 CPU 调频并考虑其他稳定系统性能的手段。这条警告并非装饰性提示而是由 benchmark 库在初始化 Reporter 上下文时实际探测内核状态后打印的。在 src/reporter.cc 中if (CPUInfo::Scaling::ENABLED info.scaling) { Out ***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.\n; }而info.scaling的取值来自 src/sysinfo.cc 中的CpuScaling()函数CPUInfo::Scaling CpuScaling(int num_cpus) { // We dont have a valid CPU count, so dont even bother. if (num_cpus 0) return CPUInfo::Scaling::UNKNOWN; #if defined(BENCHMARK_OS_QNX) return CPUInfo::Scaling::UNKNOWN; #elif !defined(BENCHMARK_OS_WINDOWS) // On Linux, the CPUfreq subsystem exposes CPU information as files on the // local file system. ... std::string res; for (int cpu 0; cpu num_cpus; cpu) { std::string governor_file StrCat(/sys/devices/system/cpu/cpu, cpu, /cpufreq/scaling_governor); if (ReadFromFile(governor_file, res) res ! performance) return CPUInfo::Scaling::ENABLED; } return CPUInfo::Scaling::DISABLED; #else return CPUInfo::Scaling::UNKNOWN; #endif }从源码逻辑可以明确两点检测规则仅逐核检查 Linux 的 CPUFreq 接口对每个 CPU 读取/sys/devices/system/cpu/cpuN/cpufreq/scaling_governor只要任意一个核的 governor 不是performance就判定为调频已启用并打印警告读取失败则静默如果这些 sysfs 文件不可读例如非 Linux 系统、未启用 CPUFreq函数返回UNKNOWN不会误报警告。这也解释了为什么在部分平台上你永远看不到这条警告。同一个scaling状态还会影响频率的读取策略在 src/sysinfo.cc 的GetCPUCyclesPerSecond()中当 scaling 为DISABLED时优先读取scaling_cur_freq当前频率否则倾向于使用更高的标称频率避免把降频时读到的低频当成 CPU 的真实频率。二、关闭 CPU 调频使用 cpupower 切换到 performance 模式如何具体关闭调频取决于 Linux 发行版、桌面环境和已安装的程序细节因系统而异。文档给出了一个简单而通用的方案使用与内核一同维护、由发行版提供的cpupower工具把处理器性能调节器governor改为performance。步骤 1以 root 身份设置 performance governorsudo cpupower frequency-set --governor performance步骤 2验证所有 CPU 均已使用 performance governorcpupower frequency-info -o proc执行上述设置后再运行 benchmark单次测量之间的抖动会明显减少——因为每个核都锁定在标称最高频率上运行不再随负载波动。这也正是上面CpuScaling()判定scaling DISABLED的前提条件。三、调频之外基准测试噪声的六大来源CPU 调频只是噪声来源之一。在 docs/reducing_variance.md 中完整的噪声来源清单如下多核机器上各 CPU/核心/线程速率不一致同一个 benchmark 跑一次和再跑一次可能因为落在了不同的 CPU 核心上而得到不同结果CPU 内部加速特性如 Intel Turbo Boost、AMD Turbo Core 和 Precision Boost。这类特性即使在 Linux 下使用performancegovernor 时也可能临时改变 CPU 频率上下文切换与 benchmark 所运行 CPU 上的调度竞争Intel Hyperthreading / AMD SMT超线程核与上面第 3 条造成同类问题同物理核上的两个逻辑核互相干扰其他 CPU 上运行的代码造成的缓存效应cache effects非一致性内存架构NUMA跨 NUMA 节点访存延迟不同。这些噪声既可能体现在单次运行内部即通过--benchmark_repetitionsN进行的重复测量之间也可能体现在多次独立运行整个 benchmark 程序之间。由于方差来源与操作系统和硬件架构强相关这也是许多公司维护专门用于性能测试的专用机器dedicated machines的原因之一。四、降低方差的实操手段典型 Linux 工作站原文档给出了典型 Linux 工作站上较易操作且效果明显的若干手段逐条说明如下。4.1 使用 performance governor如第二节所述用cpupower把 governor 设为performance。这是所有手段的基础。4.2 关闭处理器加速Boost即使 governor 是performanceTurbo Boost 之类的加速仍会临时超频。关闭方式echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost该 sysfs 节点的作用可参考 Linux 内核文档Documentation/cpu-freq/boost.txt的说明。4.3 用 taskset 固定 CPU 亲和性将 benchmark 进程绑定到固定 CPU消除落在哪个核上的随机性taskset -c 0 ./mybenchmark绑定单核后第 1、2、3 类噪声核心速率差异、调度竞争、上下文切换都会被显著削弱。4.4 关闭 Hyperthreading/SMT可以在 BIOS 中关闭也可以通过/sys文件系统操作LLVM 项目在其 Benchmarking 文档中给出了基于 sysfs 的具体做法。关闭 SMT 直接消除第 4 类噪声避免同物理核上的兄弟逻辑核干扰。4.5 关闭其他基于定时器做事的程序关闭浏览器、桌面环境等会基于定时器执行非平凡工作的程序减少第 3、5 类噪声调度竞争与缓存干扰。4.6 把工作集收敛到 L1 缓存内缩小 benchmark 的工作集working set使其能放进 L1 缓存可以消除缓存层级带来的波动但文档特别提醒这种做法可能让你在不真实unrealistic的场景上过度优化需要权衡取舍。五、库内机制--benchmark_repetitions 与统计聚合压低环境噪声之外benchmark 库本身还提供用多次测量 统计聚合来对抗残余方差的第一道防线。命令行参数--benchmark_repetitionsnum_repetitions默认值为 1定义见 src/benchmark.ccBM_DEFINE_int32(benchmark_repetitions, 1);每个 benchmark 也可以单独通过.Repetitions(n)设置在 src/benchmark_runner.cc 中实例级设置优先于全局 flagrepeats(b.repetitions() ! 0 ? b.repetitions() : FLAGS_benchmark_repetitions),重复测量的执行流程BenchmarkRunner::DoOneRepetition()src/benchmark_runner.cc中有一个关键设计——迭代次数只在第一次重复时通过PredictNumItersNeeded()逐轮放大估算得到之后的重复直接复用第一次计算出的迭代次数保证各次重复在相同的测量长度下比较。所有重复完成后GetResults()调用ComputeStats()对这一组报告做统计聚合src/benchmark_runner.cc// Calculate additional statistics over the repetitions of this instance. run_results.aggregates_only ComputeStats(run_results.non_aggregates);统计实现ComputeStats()位于 src/statistics.cc它要求至少两次非跳过的运行才会产生聚合结果单次运行不报告聚合数据。聚合指标包括指标实现说明meanStatisticsMean算术平均medianStatisticsMedian样本数少于 3 时退化为均值偶数个样本取中位两侧均值使用nth_element部分排序stddevStatisticsStdDev样本标准差n-1 分母n1 时返回 0cvStatisticsCV变异系数 标准差 / 均值样本少于 2 个或均值为 0 时返回 0可以推断cv变异系数正是用来直观衡量重复测量之间的相对离散程度的如果你的 repetitions 结果 cv 明显偏高说明环境噪声尚未压干净应回到第四节逐项排查而不是急于解读 mean 的绝对值。六、进阶随机交错Random Interleaving仓库中另有一篇文档 docs/random_interleaving.md 专门介绍针对运行间方差run-to-run variance的随机交错技术把同一微基准的多次重复与其他微基准的重复随机交错执行据该文档引用的上游数据平均可降低约 40% 的运行间方差。使用方式--benchmark_enable_random_interleavingtrue \ --benchmark_repetitions9 \ --benchmark_min_time0.1其中 repetitions 非零值与较短的单次测量时间通常配合使用。这项技术与本文的环境级降噪手段互补前者从调度时序上打散系统性偏差后者从硬件状态上消除波动根源实际工作中可以叠加使用。七、验证你的降噪效果一条可操作的检查清单将上述内容串起来得到一个可落地的操作序列运行 benchmark确认输出头部不再出现***WARNING*** CPU scaling is enabled...若出现说明仍有核的 governor 不是performance见第一节检测逻辑sudo cpupower frequency-set --governor performance并用cpupower frequency-info -o proc逐核验证echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost关闭 Boost用taskset -c 0 ./mybenchmark绑定核心条件允许时关闭 SMT加上--benchmark_repetitionsNN ≥ 3 使 median/stddev 有意义观察聚合输出中的 mean/median/stddev/cv以 cv 判断方差是否收敛。八、延伸阅读原文档末尾给出了两个主题相关的进一步学习方向此处按名称列出见原文档获取入口LLVM 项目的 Benchmarking 文档其中包含通过/sys文件系统关闭 SMT 的具体做法Arch Wiki 的 CPU frequency scaling 页面。这两份资料与本仓库的实现互相印证benchmark 库源码中对/sys/devices/system/cpu/cpu*/cpufreq/路径的直接依赖见 src/sysinfo.cc说明理解 Linux CPUFreq 的 sysfs 接口是排查基准测试方差问题的基本功。适用前提小结本文涉及的 sysfs 路径scaling_governor、cpufreq/boost与cpupower均为 Linux 平台特性从 src/sysinfo.cc 的编译分支可以看出调频检测逻辑本身仅对非 Windows/非 QNX 的类 Linux 平台生效其他平台上scaling为UNKNOWN不会出现该警告。跨平台对比测试时请额外注意各平台可用的降噪手段不同。赞分享性能测试【免费下载链接】benchmarkA microbenchmark support library项目地址https://gitcode.com/gh_mirrors/benchmark5/benchmark点击查看免费下载相关推荐Google Benchmark 降低基准测试方差完整指南CPU 调频、ASLR 与噪声控制实践Google Benchmark 降低基准测试方差完整指南CPU 调频、ASLR 与噪声控制实践 本指南以 Google Benchmark GitHub_性能测试开发工具Google Benchmark 随机交错Random Interleaving用随机化执行顺序压降低重复测量方差Google Benchmark 随机交错Random Interleaving用随机化执行顺序压降低重复测量方差 本指南以 benchmark 仓库官方性能测试开发工具google/benchmark 随机交错Random Interleaving详解降低微基准方差的原理、用法与源码实现google/benchmark 随机交错Random Interleaving详解降低微基准方差的原理、用法与源码实现 本文围绕 Google Benc性能测试上一篇Qwen3-8B-AWQ终极部署指南如何在单张消费级显卡上运行高性能大语言模型下一篇如何快速搭建私有云盘ZFile在线文件管理系统的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表