这是一篇有趣的文章!说不要使用 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,因为它很难校准;而是使用
QueryPerformanceFrequency
and
QueryPerformanceCounter
,其精确到小于 10 微秒(0.00001 秒)。
对于简单的计时,timeGetTime 和 QueryPerformanceCounter 都很好用,QueryPerformanceCounter 显然更准确。但是,如果您需要执行任何类型的“定时暂停”(例如帧速率限制所必需的暂停),则需要小心坐在调用 QueryPerformanceCounter 的循环中,等待它达到某个值;这将消耗 100% 的处理器。相反,考虑一个混合方案,当您需要通过超过 1 毫秒的时间时,您调用 Sleep(1)(不要忘记 timeBeginPeriod(1)!),然后只进入 QueryPerformanceCounter 100%-busy 循环完成您需要的最后 < 1/1000 秒的延迟。这将为您提供超精确的延迟(精确到 10 微秒),并且 CPU 使用率非常低。