std::chrono::high_resolution_clock 不保证纳秒级精度,其实际分辨率取决于系统API和硬件,即使 duration::period::den 为1,真实tick间隔可能达几十纳秒或微秒级。
std::chrono::high_resolution_clock 并不保证纳秒级精度
很多开发者看到
就默认它能返回纳秒值,实际并非如此。它的底层实现依赖系统 API(Windows 上通常是
,Linux 上是
),分辨率由硬件和内核决定。即使
是 1(即理论上支持纳秒),真实 tick 间隔可能是几十纳秒甚至微秒级。
验证方法很简单:
多次运行会发现最小差值远大于 1 —— 这就是你实际能拿到的“纳秒级”下限。
用 duration_cast 提取纳秒值,但别误以为它提升了精度
只做单位换算,不增加原始测量精度。比如 clock 返回的是以 15.625ns 为 tick 的计数器(常见于某些 Intel TSC 配置),
会把 1 个 tick 换算成 15 或 16 纳秒,但无法还原出中间的亚 tick 时间。
立即学习
“
C++免费学习笔记(深入)
”;
正确用法:统一单位做差值计算,例如测函数耗时
错误预期:认为
返回的是绝对纳秒时间戳(可用于跨进程对齐)
注意:不同 clock 类型(
、
、
)的 epoch 不同,
值不可直接比较
跨平台纳秒时间戳需组合 system_clock + steady_clock
若真需要高精度且可比的绝对时间(如日志打点、分布式 trace),不能只靠
。推荐做法是:用
获取带时区的秒级基准(保证绝对时间语义),再用
做高精度增量,定期校准偏移。
简易校准示例(非实时同步,仅示意逻辑):
C知道
CSDN推出的一款AI技术问答工具
下载
后续每次获取“高精度绝对时间”时:
注意:
会随系统时间调整漂移,生产环境需用 NTP 或 PTP 同步策略更新。
避免 std::chrono::time_point 构造时的隐式截断
当你把一个
duration 赋给
,而该 clock 的
更粗(如 microsecond),会发生向下取整截断:
这类问题在模板推导或跨 clock 转换时极易发生。安全做法是:
显式使用
并检查是否丢精度:
优先用
推导类型,避免手动指定不匹配的 clock
打印调试时,统一转成
再输出:
不可靠,应先 cast
最常被忽略的一点:
返回的
类型在不同编译器/平台可能不同(GCC 常为
,MSVC 可能是
或
),硬编码类型会导致移植失败。
high_resolution_clockQueryPerformanceCounterclock_gettime(CLOCK_MONOTONIC)duration::period::denauto t0 = std::chrono::high_resolution_clock::now();
auto t1 = std::chrono::high_resolution_clock::now();
auto diff = t1 - t0;
std::cout << "Min observed resolution: "
<< std::chrono::duration_cast(diff).count()
<< " ns\n"; duration_castduration_cast.time_since_epoch().count()system_clocksteady_clockhigh_resolution_clocktime_since_epoch()high_resolution_clocksystem_clocksteady_clockauto sys_now = std::chrono::system_clock::now();
auto steady_now = std::chrono::steady_clock::now();
auto offset = sys_now.time_since_epoch() - steady_now.time_since_epoch();auto steady_t = std::chrono::steady_clock::now();
auto abs_ns = (steady_t.time_since_epoch() + offset).count(); // 单位:纳秒,基于 system_clock epochoffsetnanosecondstime_pointperiodusing MyClock = std::chrono::duration;
std::chrono::time_point tp{
std::chrono::nanoseconds{1234} // → 实际存为 1μs,丢失 234ns
}; time_point_casttime_point_cast(tp).time_since_epoch().count() autonanosecondstp.time_since_epoch().count()std::chrono::high_resolution_clock::now()time_pointnanosecondsnanosecondspicoseconds