为什么GetTickCount和timeGetTime有不同的分辨率?

时间:2013-03-13 11:07:48

标签: windows timer performancecounter gettickcount

默认情况下,GetTickCount和timeGetTime具有相同的分辨率 - 15.625ms,但在我调用timeBeginPeriod(1)后,GetTickCount仍然每15.625 ms更新一次,而timeGetTime每1ms更新一次,为什么会这样?

Bug in waitable timers?中,作者提到:

RTC based timer

我想知道:为什么GetTickCount和timeGetTime来自同一个RTC,但有两种解决方案?

谢谢!

3 个答案:

答案 0 :(得分:1)

实际上,对于QueryPerformanceCounter,您引用的表是错误的。 QPC(简称)以3种可能的定时源实现,即1:HPET,2:PM ACPI定时器,3:RDTSC。 根据条件,内核启动选项,BIOS中的错误以及芯片组提供的ACPI代码中的错误,可以通过启发式方法做出决定。所有这些错误都是在Microsoft实验室的每个硬件基础上发现的。 Linux和BSD程序员必须自己找到硬道路,并且通常必须重写ACPI代码以解决问题。由于各种原因,Linux社区已经开始讨厌RDTSC以及ACPI。但无论如何......

timeReadTime与GetTickCount不同,因为根据指定GetTickCount的文档如何使其行为无法更改的稳定性。 然而,窗口需要在某些情况下获得更好的Tick分辨率以允许更好的Timer功能。 (定时器使用消息发送到应用程序GetMessage或PeekMessage函数,然后在良好的回调中分支来处理定时器) 这对于声音/音频同步等多媒体来说是必需的。

显然,游戏或实时编程甚至有时需要更高的精度,并且不能使用定时器。相反,他们使用繁忙的等待,或者他们只在一个场合睡觉:VSync通过调用OpenGL或DirectX uppon backbuffer / frontbuffer交换。视频驱动程序将从屏幕本身唤醒VSync信号的等待线程。这是一个基于事件的睡眠,就像一个计时器,但不是基于计时器中断。

应该注意的是,现代内核具有动态滴答(无滴漏内核,来自windows 8或linux 2.6.18)。最好的嘀嗒中断频率不能低于1ms以避免窒息,但没有上限。如果没有应用程序正在运行并且发布计时事件,则机器可以无限期地睡眠,从而允许CPU进入最深睡眠状态(Intel Enhanced Speed Step C7状态)。之后,大多数时间发生下一次唤醒事件是因为设备中断,主要是USB。 (鼠标移动或其他东西)

答案 1 :(得分:0)

我认为OP在定时器,中断和计时器滴答之间变得混乱。

量子间隔是计时器滴答周期。这是以18.2滴/秒的速度硬连线到系统中。这绝不会因任何原因而变化,并且不是基于系统CPU时钟(显然!)。

您可以向系统询问两个不同的事项:日期和时间,(GetTime)或系统运行的时间(GetTickCount / GetTickCount64)。

如果您对系统的正常运行时间感兴趣,请使用GetTickCount。根据我的有限理解,GetInterruptTime仅返回实时中断期间花费的时间(而不是运行应用程序或空闲时间)。

我不确定告诉新程序员不要再问“为什么?”会帮助他们。是的,OP没有看到或阅读上述页面上的评论;但在这里要求不应该只是给那些已经用尽所有其他途径(可能包括C的见石)的搜索者的特权。我们都在这里学习。不要告诉别人他们的问题毫无意义而没有告诉他们原因。并且没有理由不问。定时器可能令人困惑!

答案 2 :(得分:0)

对于那些对为什么系统滴答曾经以18.2Hz运行的人感到好奇的是以下解释: 1981年发布的原始IBM PC的时钟速度为4.77MHz,并使用了Intel 8253可编程间隔计时器。定时器的预分频器为4,系统定时器的编程值为0,因此计数间隔为65536。 因此系统计时器频率=(4770000/4)/ 65536 = 18.2Hz 即使现在时钟频率更高并且8253现在已经过时(但仍在芯片组中实现),所有现代PC仍然使用此配置。

现代操作系统(例如Windows 10和Linux)对此计时器进行编程,以生成1000Hz的系统时钟,而不是旧的18.2Hz。