不能直接当作“最高精度”用。它只是标准库中理论上精度最高的时钟,实际精度取决于平台和硬件;Windows 通常退化为 steady_clock,Linux 多为 CLOCK_MONOTONIC_HR;需结合 is_steady 和 period 判断;实操优先用 steady_clock 测耗时,避免 system_clock。
不能直接当作“最高精度”用。它只是标准库中定义的、理论上精度最高的时钟,但实际精度取决于平台和硬件。Windows 上通常退化为 std::chrono::steady_clock(基于 QueryPerformanceCounter),Linux 上多数是 CLOCK_MONOTONIC_HR,但 glibc 旧版本可能 fallback 到 CLOCK_MONOTONIC。关键看 std::chrono::high_resolution_clock::is_steady 返回值,以及其 period::num 和 period::den —— 比如 std::nano 表示纳秒级分辨率,但不等于能稳定测出 1ns 差异。
实操建议:
std::chrono::steady_clock:单调、无跳变、适合测量耗时,绝大多数场景更可靠std::chrono::system_clock 测间隔:它反映墙上时间,受系统时钟调整影响(NTP 同步、手动改时间都会导致负值或跳变)std::cout << std::chrono::high_resolution_clock::period::num << "/"
<< std::chrono::high_resolution_clock::period::den << "\n";若输出 1/1000000000,说明标称纳秒级;但真实抖动可能在微秒量级最常见错误是把 clock::now() 调用本身计入测量范围,或忽略编译器优化导致代码被删减。正确做法是强制防止优化 + 多次采样取最小值(排除中断、缓存未命中等噪声)。
实操建议:
volatile 或 asm volatile("" ::: "memory") 防止编译器重排或省略待测代码time_point 相减,不要跨时钟类型转换.count() 直接转整数再除法算毫秒——先转 duration 再用 duration_cast
示例(测一个简单循环):
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < 1000; ++i) {
volatile int x = i * i; // 防优化
}
auto end = std::chrono::steady_clock::now();
auto dur = end - start;
auto ns = std::chrono::duration_cast(dur).count();
std::cout << "cost: " << ns << " ns\n"; duration_cast 是向零截断(truncation),不是四舍五入。比如 999 纳秒转微秒得 0,1001 纳秒才得 1。更危险的是跨数量级转换时隐式溢出 —— 如把小时级 duration 强转成 nanoseconds,可能超出 long long 范围。
实操建议:
duration_cast,例如要毫秒就 cast 到 milliseconds,别先转 nanoseconds 再自己除 1e6seconds 或 milliseconds 存储,避免纳秒累积溢出duration_cast 取整秒,再用 duration_cast 取余下纳秒,分别处理是线程安全的,steady_clock::now() 和 high_resolution_clock::now() 都是无状态、无锁的函数调用,可安全用于多线程、信号处理函数(前提是信号处理函数中只做简单计时,不分配内存或调用非 async-signal-safe 函数)。
但要注意:
std::chrono::steady_clock::now() 是允许的(POSIX 允许的 async-signal-safe 函数子集之外,C++ 标准未明确定义,但主流实现如 libstdc++/libc++ 均基于系统调用封装,实际可用)std::cout、std::string 或任何可能触发 malloc 的操作
time_point::time_since_epoch().count() 值(它是 duration,可安全复制)真正影响精度的从来不是库接口,而是你是否关掉了 CPU 频率缩放、是否绑定了 CPU 核心、是否在虚拟机里跑 —— 这些比选哪个 clock 更关键。