操作系统时钟源的选择(TSC、HPET、ACPI_PM)
使用与兼容性
在HPET出现之前设计的操作系统不能使用HPET,因此将使用其他计时器设备。较新的操作系统往往可以使用较新与较旧的计时器。一些硬件同时有较新与较旧的计时器。事实上,目前的南桥芯片大多数也都同时支持传统的PIT、PIC、高级可编程中断控制器(APIC)和RTC设备,无论操作系统是否使用,从而有助于非常现代的PC运行旧款操作系统。
已知下列操作系统无法使用HPET:Windows XP SP2、 Windows Server 2003及更早的Windows版本,Linux内核2.6以前。
已知下列操作系统可以使用HPET:Windows XP SP3、Windows Server 2008、Windows Server 2008 R2、Windows Vista、 Windows 7、基于x86的OS X、使用2.6或更高内核的Linux操作系统以及FreeBSD。
Linux内核也可以使用HPET作为其时钟源。Red Hat MRG第二版的文档指,TSC是首选时钟源——因为它的开销低很多,而HPET作为后备时钟源。一个千万次事件计数的基准测试显示,TSC花费约0.6秒,而HPET花费略微超过12秒,ACPI电源管理计时器花费约24秒。
稳定时间戳计数器(Constant Time Stamp Counter, TSC)
现代Intel和AMD处理器提供了一个稳定时间戳计数器(Constant Time Stamp Counter, TSC)。这个稳定的TSC的计数频率不会随着CPU核心更改频率而改变,例如,节电策略导致的cpu主频降低不会影响TSC计数。一个CPU具有稳定的TSC频率对于使用TSC作为系统的时钟源是非常重要的。
要查看CPU是否具有稳定的时间戳计数器(constant TSC)需要检查cpuinfo中是否有constant_tsc标志:
cat /proc/cpuinfo | grep constant_tsc
如果上述命令没有任何输出,则表明cpu缺少稳定的TSC特性,需要采用其他时钟源。
时钟硬件和计时准确性
时间戳计数器(TSC)时钟源是当前一代 CPU 上最精确的一种。当操作系统支持 TSC 并且 TSC 可靠时,它是跟踪系统时间更好的方式。有多种方式会使 TSC 无法提供准确的计时源,这会让它不可靠。旧的系统能有一种基于 CPU 温度变化的 TSC 时钟,这让它不能用于计时。尝试在一些就的多核 CPU 上使用 TSC 可能在多个核心之间给出不一致的时间报告。这可能导致时间倒退,这个程序会检查这种问题。并且即使最新的系统,在非常激进的节能配置下也可能无法提供准确的 TSC 计时。
更新的操作系统可能检查已知的 TSC 问题并且当它们被发现时切换到一种更慢、更稳定的时钟源。如果你的系统支持 TSC 时间但是并不默认使用它,很可能是由于某种充分的理由才禁用它。某些操作系统可能无法正确地检测所有可能的问题,或者即便在知道 TSC 不精确的情况下也允许使用 TSC。
如果系统上有高精度事件计时器(HPET)并且 TSC 不准确,该系统将会更喜欢 HPET 计时器。计时器芯片本身是可编程的,最高允许 100 纳米的解析度,但是在你的系统时钟中可能见不到那么高的准确度。
高级配置和电源接口(ACPI)提供了一种电源管理(PM)计时器,Linux 把它称之为 acpi_pm。得自于 acpi_pm 的时钟最好时将能提供 300 纳秒的解析度。
在旧的 PC 硬件上使用的计时器包括 8254 可编程区间计时器(PIT)、实时时钟(RTC)、高级可编程中断控制器(APIC)计时器以及 Cyclone 计时器。这些计时器是以毫秒解析度为目标的。
改变时间来源
在一些较新的 Linux 系统上,可以在任何时候更改用来收集计时数据的时钟来源。以下例子显示了在系统上切换到较慢的 acpi_pm 时钟源:
# cat /sys/devices/system/clocksource/clocksource0/available_clocksource
tsc hpet acpi_pm
# echo acpi_pm > /sys/devices/system/clocksource/clocksource0/current_clocksource
FreeBSD 也允许即时更改时钟源,并且它会记录在启动期间有关计时器选择的信息:
# dmesg | grep "Timecounter"
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
Timecounter "i8254" frequency 1193182 Hz quality 0
Timecounters tick every 10.000 msec
Timecounter "TSC" frequency 2531787134 Hz quality 800
# sysctl kern.timecounter.hardware=TSC
kern.timecounter.hardware: ACPI-fast -> TSC
总结
1、如果CPU支持(constant TSC)特性,那么优先选择TSC时钟源;
2、如果没有(constant TSC)特性,选择HPET;
constant TSC > HPET > ACPI_PM > TSC > i8254