std::chrono::high_resolution_clock 实际最小分辨率不保证纳秒级,Linux通常为1–15纳秒,Windows现代设备为10–100纳秒,虚拟机或老旧系统可能退化至微秒级;真实抖动常为理论周期的2–5倍。

chrono::high_resolution_clock 的实际最小分辨率是多少
它不保证是纳秒级,具体精度取决于平台和硬件。Linux 上通常为 1–15 纳秒,Windows 上多数现代设备在 10–100 纳秒之间,但某些虚拟机或老旧 BIOS 可能退化到微秒级。用 std::chrono::high_resolution_clock::period::num 和 std::chrono::high_resolution_clock::period::den 可查理论周期,但真实抖动常比理论值大 2–5 倍。
为什么 clock() 和 GetTickCount 不适合测函数开销
它们的最小可分辨间隔远大于函数调用本身开销,导致测量结果恒为 0 或严重失真:
-
clock()在 Windows 下默认按毫秒计(CLOCKS_PER_SEC == 1000),Linux 下虽可能为 1000000,但受内核调度粒度限制,仍难稳定捕获 sub-millisecond 行为 -
GetTickCount()固定 15.6 ms 分辨率(64 Hz 系统时钟),连 sleep(1) 都测不准,更别说函数调用开销 - 二者都统计“挂钟时间”或“CPU 时间总和”,无法排除上下文切换、中断、缓存预热等干扰
如何避免测量噪声压过真实开销
单次调用 std::chrono::high_resolution_clock::now() 的开销本身就在 10–50 纳秒量级,若被测函数更快,测出来的就主要是计时器自身抖动。必须用以下方式摊薄误差:
- 对目标函数循环执行 N 次(N ≥ 10000),再除以 N 得平均值
- 用
volatile或强制内存访问防止编译器优化掉被测逻辑(例如volatile int sink = result;) - 在 Release 模式下编译,且关闭
-fno-rtti等干扰 ABI 的选项——某些调试符号注入会拖慢时钟读取 - 重复运行整个测量块 5–10 次,剔除最大最小值后取中位数,比均值更能抵抗瞬时系统抖动
内联函数会让测量失效吗
会,而且非常隐蔽。如果被测函数被编译器内联,start 和 end 之间实际包裹的是展开后的指令流,不再是“函数调用开销”,而是“逻辑体执行时间”。解决方法只有两个:
立即学习“C++免费学习笔记(深入)”;
- 加
__attribute__((noinline))(GCC/Clang)或__declspec(noinline)(MSVC)强制禁止内联 - 把函数体拆进独立 .cpp 文件,并确保链接时不启用 LTO(Link-Time Optimization),否则跨文件内联仍会发生
别依赖 inline 关键字——它只是建议,编译器完全可以忽略;也别在头文件里测模板函数,实例化后是否内联完全不可控。


















