2

我知道我可以使用 IRQ0,它是系统定时器,但这基于 14.31818MHz 时钟,对吗?有什么能提供更高的精度吗?

谢谢。

编辑:有谁知道 Windows 函数 QueryPerformanceCounter 使用什么?

4

2 回答 2

3

“精度”和“准确度”意味着不同的东西。“地球的周长是 40000.000000000 公里”是精确的,但并不精确。时钟有点复杂:

  • 分辨率:滴答之间的时间,或滴答的周期。(你可以称它为“精度”,但我认为“分辨率”有更明显的含义。)
  • 偏斜:标称和实际时钟频率之间的相对差异(ish)
  • 漂移:偏斜变化率(由于老化、温度等)。
  • 抖动:滴答时间的随机变化。
  • 延迟:获取时间戳需要多长时间。

即使“系统计时器”(根据 Wikipedia 的PIT)以 1.something MHz 运行,您通常会在 100 到 1000 Hz 之间获得 IRQ0。显然你也可以从端口 0x40 读取两次以获得当前的计数器值,但我不确定这有什么样的延迟(然后你会在下一次中断之前得到计数,所以你需要做一些数学运算) . 它也不适用于更现代的“无滴答”内核。

还有一些其他的高频定时器:

  • 本地 APIC,它基于总线频率和 2 的幂分频器。我找不到任何关于如何阅读它的文档(大概它是一个 I/O 端口?)。
  • ACPI 电源管理计时器(Linux 中的 acpi_pm;我认为,还有 /UsePMTimer Windows 启动标志),根据this大约是 3.58 MHz 。IIRC,阅读它有点贵。
  • HPET,根据同一链路至少为 10 MHz(但可以更高)。它还应该具有比 ACPI PM 计时器更低的延迟。
  • TSC(有警告)。几乎可以肯定是最低延迟,也可能是最高频率。(但显然每个“滴答声”它可以增加超过 1,因此每秒计数不一定与分辨率相同。)

Darwin(即 OS X)似乎假设 TSC 频率没有改变,并在从 TSC 未运行的睡眠状态(显然 C4 和更高)唤醒时调整添加到它的基本值。每个 CPU 有不同的基值,因为 TSC 不需要跨 CPU 同步。您必须付出合理的努力才能获得合理的时间戳。

IIRC,Linux 只选择一个时钟源(TSC,如果它是理智的,然后是 HPET,然后是 ACPI PM,我认为)。

IIRC,QueryPerformanceCounter() 使用 Windows 认为最好的任何东西。它在某种程度上也取决于 Windows 版本(据说 XP 不支持 HPET 中断,所以大概也不支持时间戳)。您可以调用 QueryPerformanceFrequency() 进行猜测(我得到 1995030000,这可能意味着它是 TSC)。

于 2010-10-02T04:07:25.470 回答
1

Intel 处理器通常具有通过rdtsc指令获得的高精度计时器信息。

它的精度远高于 14 MHz¹。需要注意的是,它可能会在多核和速度步进处理器上出现问题。

编辑: 这个问题有更多关于这个主题的细节。


1. 实际频率取决于处理器——但通常是处理器频率。显然,在 Nehalem 处理器上,TSC 以前端总线频率 (133 MHz) 运行。

于 2010-09-30T22:01:18.977 回答