是否可以使用查询性能计数器(Win32,C++)获取时间戳?如果不是,在 Win32-C++ 应用程序上获取时间戳的最准确方法是什么?
2 回答
QueryPerformanceCounter
只是一个计数器,在机器开机并向上计数时包含一些值。它根本没有连接到挂钟。
GetSystemTime
GetSystemTimeAsFileTime
如果足够好的话,精确到~15ms 。
如果您仅针对 Windows 8,则GetSystemTimePreciseAsFileTime
非常精确。
如果您需要在 Windows pre 8 上获得真正高分辨率的时间,您可以尝试使用系统时间和性能计数器的混合方法,类似于此处概述的内容:Implement a Continuously Updating, High-Resolution Time Provider for Windows
如果您使用的是 C++ 11,那么您可能还想看看std::chrono::system_clock
or std::chrono::high_resolution_clock
。
您在硬件中有哪些时钟源?
如果您需要准确性,则不能使用 QueryPerformaceCounter,因为它与 CPU 时钟同步,速度很快但不准确。
中断定时器:这个定时器产生一个频率为 1 kHz 的中断,并且可能非常精确。
HPET:一个 1 MHz 定时器。这是您要使用的。
音频接口采样时钟:该时钟的频率取决于音频采样率,但中断频率取决于音频缓冲区大小,通常要求大于几毫秒。
我已成功使用 Waitable Timer 以 40 ms 的间隔驱动屏幕捕获程序。有关演示,请参阅:http ://www.youtube.com/watch?v=SLad8-IRtg4 。音轨是通过从音频输出到音频输入的模拟反馈记录下来的,这表明帧时钟与音频设备的采样时钟保持同步。相同的时钟应该在 1 毫秒内工作,但当机器忙于渲染 3d 内容并将视频帧压缩为 PNG 时则不行:-)
要使用音频设备时钟,请记录到虚拟缓冲区。在 Windows 7 上,使用新的音频架构来获得尽可能小的缓冲区大小。在旧系统上,您需要内核流。如果您想要音频,您还可以将函数发生器插入到您的波形设备中,并使用一个循环来返回基于触发条件的时间戳。这样,您将低于 1 毫秒。