【问题标题】:What's the most accurate way of measuring elapsed time in a modern PC?在现代 PC 中测量经过时间的最准确方法是什么?
【发布时间】:2010-09-30 21:53:08
【问题描述】:

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

谢谢。

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

【问题讨论】:

  • 实际上是 14.31818 MHz / 12 = 1.193181 MHz。请注意,这些是兆赫兹,即每秒数百万个周期,您需要什么样的精度?如果您不需要类似 TSC 的精度,也许 HPET 就足够了?
  • 嗯,我收到了相互矛盾的信息。一些消息来源说 14.31818MHz,其他人只是说“系统时钟”,现在你说它是 1.193181 MHz。困惑。
  • 这里是关于QueryPerformanceCounter的问题的答案。

标签: assembly timer system clock irq


【解决方案1】:

“Precision”和“accuracy”有不同的含义。 “地球的周长是 40000.000000000 公里”是精确的,但并不精确。时钟有点复杂:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

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


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

    【讨论】:

    • IIRC,RDTSC 从 Pentium 就已经存在,曾经是一个循环计数器。是否理智与处理器高度相关;有一些处理器标志是否会随着 CPU 频率而变化(在 Linux 上,/proc/cpuinfo 中的 constant_tsc),但即使使用 constant_tsc,它仍然会受到睡眠状态的影响。
    • @tc:另外,不同 CPU/内核之间是否同步取决于处理器。
    猜你喜欢
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 2015-02-01
    • 2021-05-25
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多