在现代PC中测量经过时间的最准确方法是什么?

时间:2010-09-30 21:53:09

标签: assembly timer system clock irq

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

感谢。

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

2 个答案:

答案 0 :(得分:2)

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

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

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

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

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

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

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

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

答案 1 :(得分:1)

英特尔处理器通常通过rdtsc指令提供高精度定时器信息。

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

编辑: This question有关于此主题的更多详细信息。


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