c++oding="utf-8" ?>
std::chrono::steady_clock是跨平台纳秒级时间测量最可靠选择,但需注意其非unix时间戳、精度依赖硬件及编译器支持,linux可用clock_gettime(clock_monotonic)、windows需queryperformancecounter配合频率换算。

用 std::chrono::steady_clock 获取纳秒级时间戳最可靠
Windows 和 Linux 下都支持,且不随系统时钟调整跳变,适合做间隔测量或超低延迟场景。但要注意:它返回的是自某个未指定起点的纳秒数,不是 Unix 时间戳。
-
std::chrono::steady_clock::now().time_since_epoch().count()返回long long类型纳秒值,直接可用 - 不要用
system_clock替代——它可能被 NTP 调整,导致时间倒流或跳跃 - 某些旧编译器(如 GCC 4.8)默认只到微秒精度,需确认
steady_clock::period::num == 1 && steady_clock::period::den == 1000000000
Linux 下用 clock_gettime(CLOCK_MONOTONIC) 更底层可控
绕过 C++ 标准库封装,直接调用 POSIX 接口,能明确控制时钟源和误差边界,适合对时序敏感的服务(如高频交易、实时音频)。
- 必须包含
<time.h></time.h>,链接时无需额外库 -
CLOCK_MONOTONIC不受系统时间修改影响;CLOCK_MONOTONIC_RAW还绕过 NTP 频率校正,精度更高但漂移略大 - 返回的
struct timespec中tv_nsec是纳秒部分,需换算:tv_sec * 1000000000LL + tv_nsec - 注意
tv_nsec范围是 [0, 999999999],加法时防溢出
Windows 下避免 GetTickCount64,改用 QueryPerformanceCounter
GetTickCount64 最高只到毫秒,且会滚回;真正纳秒级必须用高性能计数器(HPET 或 TSC),配合 QueryPerformanceFrequency 换算。
- 先调用
QueryPerformanceFrequency(&freq)获取频率(通常为 10–30 MHz,不是 1 GHz!) - 再调用
QueryPerformanceCounter(&counter),纳秒值 =counter.QuadPart * 1000000000 / freq.QuadPart - 结果是近似纳秒,实际分辨率取决于硬件——多数 x86 CPU 的 TSC 可达 ~0.3 ns,但开启节能或迁移 CPU 后可能不准
- 若需跨核心/跨 socket 稳定性,建议绑定线程到固定 CPU,并检查
IsProcessorFeaturePresent(PF_RDTSCP_INSTRUCTION_AVAILABLE)
跨平台封装要注意精度“假象”和时钟偏移
写一个通用函数看似简单,但容易误以为得到了真·纳秒精度。实际上,两次读取之间的最小间隔、缓存一致性、编译器重排都会影响结果。
- 用
volatile读取或std::atomic_thread_fence(std::memory_order_acquire)防止指令重排 - 连续两次
steady_clock::now()测得的最小差值(即时钟粒度)在不同机器上差异很大:Intel i7 可能是 15–40 ns,ARM64 可能是 100+ ns - 如果需要与 Unix 时间对齐(比如日志打标),得用
system_clock::to_time_t+steady_clock::now()做一次校准,但之后不能假设二者速率一致 - 不要把纳秒值直接转成字符串再解析——
std::to_string在某些 libstdc++ 版本下会截断高位
实际用的时候,先跑个本地测试:循环 1000 次读取时间差,看分布。低于 100 ns 的抖动基本就是硬件能力边界了,再优化没意义。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











