确定 Linux 上的 TSC 频率

Determine TSC frequency on Linux

提问人:BeeOnRope 提问时间:8/19/2018 最后编辑:BeeOnRope 更新时间:8/20/2018 访问量:6047

问:

给定一个具有恒定 TSC 的 x86,这对于测量实时时间很有用,如何使用 Linux 在启动时计算的 TSC 校准因子在 TSC 参考周期的“单位”和正常人类实时单位(如纳秒)之间进行转换?

也就是说,人们当然可以通过在某个间隔的两端进行 TSC 和时钟测量(例如,用 )来计算用户空间中的 TSC 频率,但 Linux 已经在启动时进行了这种计算,因为它在内部使用 TSC 来帮助计时。CLOCK_MONOTONIC

例如,你可以用以下命令查看内核的结果:dmesg | grep tsc

[    0.000000] tsc: PIT calibration matches HPET. 2 loops
[    0.000000] tsc: Detected 3191.922 MHz processor
[    1.733060] tsc: Refined TSC clocksource calibration: 3192.007 MHz

在更糟糕的情况下,我想你可以尝试在运行时将结果从中剔除,但坦率地说,这似乎很糟糕、脆弱和各种糟糕的0dmesg

使用内核确定的校准时间有很多优点:

  1. 您不必自己编写 TSC 校准例程,而且您可以非常确定 Linux 是同类最佳的。
  2. 当使用现有二进制文件的新内核出现时,您会自动采用TSC校准中的新技术(例如,最近芯片开始使用叶0x15宣传其TSC频率,因此校准并不总是必要的)。cpuid
  3. TSC 校准不会减慢启动速度。
  4. 在每次运行进程时(至少在重新启动之前)都使用相同的 TSC 值。
  5. 您的 TSC 频率在某种程度上与操作系统计时功能(如 和 1)使用的 TSC 频率“一致”。gettimeofdayclock_gettime
  6. 内核能够在启动时很早就进行 TSC 校准,在内核模式下,不受中断和其他进程的困扰,并且能够访问底层硬件定时器方向作为其校准源。

不过,这并不全是肉汁,使用 Linux 的 TSC 校准的一些缺点包括:

  1. 它不会在每个 Linux 安装(例如,那些不使用 tsc clocksource 的安装)或其他操作系统上都有效,因此您可能仍然需要编写回退校准方法。
  2. 有理由相信,“最近”的校准可能比旧的校准更准确,尤其是在启动后立即进行的校准:晶体行为可能会发生变化,尤其是随着温度的变化,因此您可以通过在接近使用点的地方手动进行校准来获得更准确的频率。

0 例如:系统可能尚未安装,您可能无法以普通用户身份运行它,累积的输出可能已经换行,因此行不再存在,您可能会在 grep 上收到误报,内核消息是英文散文并且可能会更改,可能很难启动子进程, 等等,等等。dmesg

1 这是否重要还有待商榷 - 但如果将调用与也使用操作系统计时的代码混合在一起,它可能会提高精度。rdtsc

Linux 性能 x86 RDTSC

评论

1赞 Margaret Bloom 8/19/2018
也许是 tsc.c 中导出的符号?只是一个猜测。tsc_khz
2赞 BeeOnRope 8/19/2018
@MargaretBloom - 似乎有人试图暴露这一点,但我想补丁从未成功过,因为我在当前源代码中没有看到它。
0赞 Peter Cordes 8/20/2018
累积的输出可能很大,:实际发生的是固定大小的内核日志缓冲区环绕,因此输出中不再存在启动时消息。dmesg
2赞 BeeOnRope 8/20/2018
@PeterCordes - 是的,你盒子上的这个值和我的盒子来自我可以直接访问的叶子。问题在于 (a) 您需要知道 CPU 的“晶体频率”,该频率因型号而异,更糟糕的是,Skylake-X 甚至在同一型号中也会有所不同,并且 (b) 在某些 CPU 上(如 Skylake-X)进行实际校准显然更好,即使您有 cpuid 信息,因为时钟速度可能与理想值相差相当大, 例如,请参阅此处cpuid0x15
1赞 maxschlepzig 9/28/2019
x86 内核中获取 TSC 速率可能重复

答: 暂无答案