这是一篇有趣的文章!说不要使用 RDTSC,而是使用QueryPerformanceCounter。
结论:
在许多基于 Windows 的操作系统上,使用常规的 oldtimeGetTime()进行计时并不可靠,因为系统计时器的粒度可能高达 10-15 毫秒,这意味着
timeGetTime()只能精确到 10-15 毫秒。[请注意,高粒度出现在基于 NT 的操作系统上,如 Windows NT、2000 和 XP。Windows 95 和 98 往往具有更好的粒度,大约 1-5 毫秒。]
但是,如果您
timeBeginPeriod(1)在程序开始(和 timeEndPeriod(1)结束)调用,timeGetTime()通常会精确到 1-2 毫秒,并且会为您提供极其准确的计时信息。
Sleep()行为相似;Sleep()实际休眠的时间长度与 的粒度密切相关timeGetTime(),因此在调用 timeBeginPeriod(1)一次后,
Sleep(1)实际上将休眠 1-2 毫秒,Sleep(2)持续 2-3 毫秒,依此类推(而不是以高达10-15 毫秒)。
对于更高精度的计时(亚毫秒精度),您可能希望避免使用汇编助记符 RDTSC,因为它很难校准;而是使用
QueryPerformanceFrequencyand
QueryPerformanceCounter,其精确到小于 10 微秒(0.00001 秒)。
对于简单的计时,timeGetTime 和 QueryPerformanceCounter 都很好用,QueryPerformanceCounter 显然更准确。但是,如果您需要执行任何类型的“定时暂停”(例如帧速率限制所必需的暂停),则需要小心坐在调用 QueryPerformanceCounter 的循环中,等待它达到某个值;这将消耗 100% 的处理器。相反,考虑一个混合方案,当您需要通过超过 1 毫秒的时间时,您调用 Sleep(1)(不要忘记 timeBeginPeriod(1)!),然后只进入 QueryPerformanceCounter 100%-busy 循环完成您需要的最后 < 1/1000 秒的延迟。这将为您提供超精确的延迟(精确到 10 微秒),并且 CPU 使用率非常低。