Windows系统C++实现1ms精度耗时计算及SYSTEMTIME比较方法
Windows平台1ms精度耗时统计方案选择
测两次调用的间隔属于时间差测量场景,不要用日历时间类API,公认最优实现按优先级排:
- 首选
QueryPerformanceCounter(QPC):这是专门为高精度时间间隔测量设计的API,底层读取硬件单调计数器,不受系统时间调整、NTP同步、用户手动改时间、时区变更影响,精度可达微秒级,完全覆盖1ms的需求,调用开销极低。
用法非常固定:程序初始化时调用一次QueryPerformanceFrequency获取计数器频率(单位:计数/秒),每次打点调用QueryPerformanceCounter拿到当前计数值,两次打点的计数值做差后,用差值 * 1000.0 / 频率就能得到毫秒级耗时。现代Windows已经处理了多核心的计数器同步问题,不用考虑CPU核心切换带来的计数偏差。 - 你提到的
QueryUnbiasedInterruptTime不是首选:这个API返回的是系统启动后的非睡眠运行时长,精度受系统时钟中断周期影响,默认Windows时钟中断间隔是10~16ms,除非你提前调用timeBeginPeriod(1)把系统定时器精度调到1ms,否则达不到要求的1ms精度;另外它的统计值排除了系统睡眠、休眠的时长,更适合统计线程/进程的活跃运行时间,不适合通用场景的耗时测量。 - 绝对不要用
SYSTEMTIME做耗时统计:SYSTEMTIME是日历时间结构体,存的是年、月、日、时、分、秒、毫秒字段,对应的是墙上绝对时间,会随NTP校时、用户手动改时间出现跳变,两次取值的差值可能为负,根本不适合做间隔计算。
SYSTEMTIME对象的比较方法
不要自己拆分年、月、日、时、分、秒、毫秒字段做比较/算差值,要处理跨日、跨月、闰年、闰秒的边界逻辑,出错概率极高,最高效简便的方式是借助系统API转换后比较:
- 调用
SystemTimeToFileTime把两个SYSTEMTIME结构转成FILETIME结构,FILETIME本质是两个32位整数拼接成的64位无符号值,代表从1601年1月1日起累计的100纳秒间隔数,是连续无跳变的时间值。 - 比较逻辑可以二选一:
- 把两个
FILETIME的高低位拼成ULONGLONG类型的64位整数,直接用整数比较运算符判断大小,整数差值除以10000就能得到毫秒级时间差,示例代码:
- 把两个
SYSTEMTIME st_a, st_b;
// 此处完成st_a、st_b的赋值
FILETIME ft_a, ft_b;
SystemTimeToFileTime(&st_a, &ft_a);
SystemTimeToFileTime(&st_b, &ft_b);
ULONGLONG time_a = (static_cast
ULONGLONG time_b = (static_cast
// time_a > time_b 即st_a时间晚于st_b
// 毫秒差 = (time_b - time_a) / 10000
- 如果只需要判断时间先后不需要算具体差值,直接调用`CompareFileTime`传入两个`FILETIME`指针即可,返回值小于0代表前者早于后者,等于0代表时间一致,大于0代表前者晚于后者,连整数拼接的步骤都省了。 > 补充提醒:哪怕通过转FILETIME的方式能计算SYSTEMTIME的差值,也不要用这个路径做1ms精度的耗时统计,SYSTEMTIME的设计定位从来不是高精度间隔测量。 内容的提问来源于stack exchange,提问作者user16541120
相关产品推荐
相关产品推荐

