6

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

等待计时器中的错误?,作者提到:

基于 RTC 的定时器

我想知道:为什么GetTickCount和timeGetTime来自同一个RTC,但有两种分辨率?

谢谢!

4

3 回答 3

1

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

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

显然,游戏或实时编程有时甚至需要更高的精度,并且不能使用计时器。相反,他们使用忙等待,或者他们只在一种情况下睡觉:通过调用 OpenGL 或 DirectX 进行后缓冲区/前缓冲区交换时的 VSync。视频驱动程序将根据来自屏幕本身的 VSync 信号唤醒等待线程。这是一个基于事件的睡眠,就像一个定时器,但不是基于定时器中断。

应该注意的是,现代内核具有动态滴答(tickless kernel,来自 windows 8 或 linux 2.6.18)。滴答中断的最细频率不能低于 1ms 以免阻塞,但没有上限。如果没有应用程序正在运行并发布计时事件,则机器可能会无限期地休眠,从而使 CPU 进入最深的休眠状态(英特尔增强速度步骤 C7 状态)。在这之后,下一个唤醒事件大部分时间是由于设备中断(主要是 USB)而发生的。(鼠标移动或其他东西)

于 2013-06-05T10:38:08.890 回答
1

我认为 OP 在定时器、中断和定时器滴答之间感到困惑。

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

您可以向系统询问 2 个不同的内容:日期和时间 (GetTime) 或系统运行的时间量 (GetTickCount/GetTickCount64)。

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

我不确定告诉新程序员不要再问“为什么?” 会帮助他们。是的,OP 没有看到或阅读提到的页面上的评论;但在这里提问不应该是只授予已经用尽所有其他途径(可能包括 C 的 Seeing Stones)的搜索者的特权。我们都在这里学习。停止告诉人们他们的问题是没有意义的,而不告诉他们为什么。没有理由不问。计时器可能会令人困惑!

于 2013-05-03T07:54:09.583 回答
1

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

然而,现代操作系统(如 Windows 10 和 Linux)对这个计时器进行编程以生成 1000Hz 的系统滴答声,而不是旧的 18.2Hz。

于 2019-09-05T06:25:34.950 回答