最可靠跨平台获取微秒级时间戳的方式是 std::chrono::steady_clock 配合 std::chrono::microseconds,它不随系统时钟跳变,适合测量间隔,但实际精度取决于平台硬件支持;windows 可用 queryperformancecounter 手动校准,linux/macos 应优先使用 clock_gettime(clock_monotonic),避免 gettimeofday 和 system_clock。

用 std::chrono::steady_clock 获取微秒级时间戳
标准库中最可靠、跨平台的方式是 std::chrono::steady_clock,它不随系统时钟调整跳变,适合测量间隔;配合 std::chrono::microseconds 可直接得到微秒整数。
注意:不是所有平台都原生支持微秒级分辨率(比如某些 Windows 环境下 steady_clock 实际精度仍是 15.6ms),但返回值始终是微秒单位,只是低位可能恒为 0。
示例:
auto now = std::chrono::steady_clock::now(); auto us = std::chrono::duration_cast<:chrono::microseconds>(now.time_since_epoch()).count(); // 返回自 epoch 起的微秒数(类型为 long long) </:chrono::microseconds>
- 避免用
system_clock——它可能因 NTP 调整倒退或跳跃,不适合计时 - 若只需相对差值(如函数耗时),直接用
duration_cast<microseconds>(end - start)</microseconds>,更安全 - Windows 上若发现
count()每次变化步长远大于 1,说明底层硬件/驱动未暴露高精度计时器,需检查是否启用QueryPerformanceCounter(steady_clock在现代 MSVC 中默认已用)
Windows 下用 QueryPerformanceCounter 手动校准微秒
当 std::chrono 表现异常(如精度卡在毫秒级),可绕过标准库直调 WinAPI。这是 Windows 唯一能稳定提供微秒甚至纳秒级分辨率的机制。
关键点在于:必须用 QueryPerformanceFrequency 换算,不能假设频率是 1MHz。
LARGE_INTEGER freq, counter; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&counter); long long microseconds = (counter.QuadPart * 1000000LL) / freq.QuadPart;
- 务必检查
freq.QuadPart是否 > 0(理论上总是成立,但某些虚拟机或旧设备可能不支持) - 除法用
1000000LL避免整型溢出;中间乘法可能超int64_t,但 Windows 下freq通常在 10^6 ~ 10^7 量级,安全 - 该值无 epoch 意义,仅用于差值计算;若要转成 wall-clock 时间,仍得靠
GetSystemTimeAsFileTime对齐
Linux/macOS 下确认 clock_gettime(CLOCK_MONOTONIC) 是否真支持微秒
POSIX 系统推荐 CLOCK_MONOTONIC,但它返回的是 struct timespec(秒 + 纳秒),实际精度取决于内核配置和硬件。很多系统声称“纳秒”接口,底层仍是微秒级 tick。
验证方法:连续调用两次,看 tv_nsec 差值最小能到多少。常见结果是 1000~15000 ns(即 1~15 微秒)。
struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); long long microseconds = ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
- 不要用
CLOCK_REALTIME测间隔——它会被 NTP slew 或 step 干扰 - glibc 2.17+ 的
clock_gettime在大多数 x86_64 Linux 上由 vDSO 提供,几乎无系统调用开销;macOS 则需通过mach_absolute_time()+ 转换,clock_gettime是较新版本才支持 - 如果
tv_nsec总是 0 或固定倍数(如只变 1000000),说明内核未启用高精度定时器(CONFIG_HIGH_RES_TIMERS=y)
为什么 gettimeofday 不再推荐
gettimeofday 返回 struct timeval(秒 + 微秒),看似完美匹配需求,但它已被标记为 legacy,且在 Linux 上本质是 CLOCK_REALTIME 的封装,受系统时钟调整影响;在 macOS 上甚至可能被模拟为粗粒度 fallback。
更严重的是:它的微秒字段(tv_usec)最大值为 999999,一旦系统时钟向后跳变(如 NTP step),连续采样会出现负差值,导致计时逻辑崩溃。
- POSIX 明确建议用
clock_gettime替代 - 即使代码跑在旧内核上,也应优先尝试
clock_gettime(CLOCK_MONOTONIC),失败后再降级 - C++20 引入了
std::chrono::utc_clock和std::chrono::tai_clock,但微秒级测量仍应坚持用steady_clock——它才是为“经过时间”而生的
实际用的时候,别只看单位是不是“微秒”,重点盯住两次读数的最小可分辨差值。这个值在不同机器、不同内核、不同编译器下都可能不一样,现场测一次比查文档管用。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











