std::chrono::high_resolution_clock不保证纳秒级精度,其实际分辨率取决于系统API和硬件;duration_cast<nanoseconds>仅单位换算,不提升精度;测量需用time_point相减后转换,避免system_clock和编译器优化干扰。

用 std::chrono::high_resolution_clock 获取纳秒级时间戳
在 C++11 及以后,std::chrono::high_resolution_clock 是最常用、最便携的高精度计时器。它不保证一定是纳秒级(取决于平台和实现),但通常是系统支持的最高精度时钟——Linux 上常映射到 CLOCK_MONOTONIC,Windows 上对应 QueryPerformanceCounter。
关键点:必须用 time_point 类型记录起点和终点,再用 duration_cast 转换为所需单位(如 nanoseconds 或 microseconds)。
- 别直接用
clock()或std::clock():它是 CPU 时间,受线程调度影响大,且精度通常只有毫秒级 - 避免用
system_clock测耗时:它可能被系统时间调整干扰(如 NTP 同步),不满足“单调性”要求 - 两次
now()调用之间尽量减少无关操作,否则会污染测量结果
auto start = std::chrono::high_resolution_clock::now(); // ... 你要测的代码 ... auto end = std::chrono::high_resolution_clock::now(); auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
为什么 duration_cast<nanoseconds> 可能返回 0
即使时钟本身支持纳秒级分辨率,duration_cast 截断的是整数纳秒值,而实际差值可能小于 1 纳秒(比如 0.7 ns)。这时 .count() 返回 0,不代表没耗时,只是低于整数纳秒粒度。
更稳妥的做法是转成 double 秒或更高精度整数类型:
立即学习“C++免费学习笔记(深入)”;
- 用
std::chrono::duration<double, std::nano>保留小数部分 - 或先转成
std::chrono::nanoseconds再调用.count(),但需意识到这是向下取整 - 若需统计多次运行的最小/平均耗时,单次为 0 很常见,应运行足够多轮(如 1000+ 次)并剔除异常值
auto dur = end - start; double ns_dbl = std::chrono::duration<double, std::nano>(dur).count(); // 例如 342.68
跨线程或长耗时测量要防优化和调度干扰
编译器可能把空循环或无副作用代码整个优化掉;OS 调度也可能让线程中途被抢占,导致测出“虚假高延迟”。这不是时钟不准,而是测量方式问题。
- 对被测代码加内存屏障或 volatile 操作(如写入
volatile int sink),防止编译器优化掉关键路径 - 用
std::this_thread::yield()或sched_yield()避免线程被长时间挂起(仅适用于调试,非生产) - 生产环境建议用多次采样 + 统计(最小值比平均值更能反映真实下界)
- 注意:
high_resolution_clock::is_steady应为true,否则说明该时钟不可靠(极少见)
Windows 下 QueryPerformanceCounter 的兼容性细节
如果你在 Windows 上需要极致控制或验证 high_resolution_clock 行为,可以直接调用 WinAPI:QueryPerformanceCounter 和 QueryPerformanceFrequency。但绝大多数场景没必要——标准库已封装好。
- 务必检查
QueryPerformanceFrequency返回值是否非零,某些老旧虚拟机可能不支持 - 频率单位是 ticks/sec,不是固定纳秒,需手动换算:
elapsed_ns = (end - start) * 1'000'000'000 / freq - 与
high_resolution_clock对齐时,注意其底层是否真用了 QPC(可通过源码或文档确认,MSVC 通常就是)
真正容易被忽略的是:哪怕硬件支持纳秒级计时,CPU 频率动态缩放(如 Intel SpeedStep)、缓存未命中、TLB miss 等都会让单次测量波动很大。想得到有意义的结果,必须结合多次采样、warm-up 运行、绑定 CPU 核心等手段——时钟本身只是工具,怎么用才决定精度。


















