前言:
计算机里的时钟硬件
真时钟RTC,在x86上的硬件实现也叫做RTC,和CMOS(计算机中有很多叫做CMOS的东西,但是是不同的概念,此处的CMOS是指BIOS设置保存数据的地方),是放在一起的。由于在关机后都需要供电,所以两者放在一起,由一个纽扣电池供电。所以有时候也会被人叫做CMOS时钟。 定时器Timer,在UP时代是PIT(Programmable Interval Timer),它以固定时间间隔向CPU发送中断信号。PIT可以在系统启动时设置每秒产生多少个定时器中断,一般设置是100,250,300,1000,这个值叫做HZ。到了SMP时代,PIT就不适用了,此时有多种不同的定时器。有一个叫做Local APIC Timer的定时器,它是和中断系统相关的。中断系统有一个全局的IO APIC,有NR_CPU个Local APIC,一个Local APIC对应一个CPU。所以在每个Local APIC都安装一个定时器,专门给自己对应的CPU发送定时器中断,就很方便。还有一个定时器叫做HPET(High Precision Event Timer),它是Intel和微软共同研发的。它不仅是个定时器,而且还有计时器的功能。HPET不和特定的CPU绑定,所以它可以给任意一个CPU发中断,这点和Local APIC Timer不同。 计时器Counter,RTC或者定时器虽然也可以实现计时器的目的,但是由于精度太差,所以系统都有专门的计时器硬件。计时器一般都是一个整数寄存器,以特定的时间间隔增长,比如说1纳秒增加1,这样两次读它的值就可以算出其中的时间差,而且精度很高。x86上最常用的计时器叫做TSC(Time Stamp Counter),是个64位整数寄存器。还有一个计时器叫做ACPI PMT(ACPI Power Management Timer),但是它是一个设备寄存器,需要通过IO端口来读取。而TSC是CPU寄存器,可以直接读取,读取速度就非常快。
Linux时间子系统的文件汇总
Clocksource: 时钟源
计算精度,从计算精度来看,mul的值肯定是越大越好,mul的值越大,得到的time值的精度也就越高,当然mul值越大,cycles的最大值就越小,这会影响到第二个因素"能耗". 能耗角度,这个和低功耗相关,因为如果系统处于idle线程的状态,会通过wfi进入低功耗状态,此时如果有中断来临,会让cpu退出,所以如果两次timer中断间隔时间太短,会增加功耗。
timer_device:时钟设备(也叫clock_event_device)
timekeeping模块
Wall time 现实时间。 MONOTONIC time: 递增时间,从系统被启动时候开始计算,但不包含cpu低功耗状态的时间。 Boot time: 递增的时间,在monotonic时间的基础上增加cpu的低功耗状态的时间。
读取rtc的效率不高,所以一般只在初始化的时候维护一次。 rtc能提供的时间精度一般很低,最多就到毫秒级别,自己通过clock_source维护可以达到ns级别。