如何获得linux gettimeofday()的微秒时间以及它的准确性是多少?

Arn*_*rno 23 linux time linux-kernel

挂钟时间通常由系统RTC提供.这主要仅提供低至毫秒范围的时间,并且通常具有10-20毫秒的粒度.但是,gettimeofday()的分辨率/粒度通常报告在几微秒范围内.我假设微秒粒度必须来自不同的来源.

gettimeofday()的微秒分辨率/粒度是如何完成的?

当从RTC获取毫微秒的部分并且从不同的硬件获取微秒时,出现了两个源的定相问题.这两个来源必须以synchronized某种方式.

这两个来源之间的同步/阶段是如何完成的?

编辑:从我在amdn提供的链接中看到的,特别是以下的英特尔链接,我在这里添加一个问题:

是否gettimeofday()在微秒制度中提供分辨率/粒度?


编辑2:总结amdns 答案以及更多阅读结果:

Linux仅在启动时使用实时时钟(RTC)与更高分辨率的计数器同步,即Timestampcounter(TSC).引导后gettimeofday()返回一个完全基于TSC值和该计数器频率的时间.frequency通过将系统时间与外部时间源进行比较来校正/校准TSC的初始值.调整由adjtimex()函数完成/配置.内核运行锁相环以确保时间结果是单调且一致的.

这样可以说gettimeofday()具有微秒分辨率.考虑到更现代的Timestampcounter在GHz体系中运行,可获得的分辨率可能在纳秒范围内.因此这个有意义的评论

/**
407  * do_gettimeofday - Returns the time of day in a timeval
408  * @tv:         pointer to the timeval to be set
409  *
410  * NOTE: Users should be converted to using getnstimeofday()
411  */
Run Code Online (Sandbox Code Playgroud)

可以在Linux/kernel/time/timekeeping.c中找到.这表明在稍后的时间点可能存在更高分辨率的功能.现在getnstimeofday()只在内核空间中可用.

但是,查看所有涉及的代码以获得正确的信息,显示了很多关于不确定性的评论.有可能获得微秒分辨率.该功能gettimeofday()甚至可以在微秒方案中显示粒度.但是:由于driftTSC频率无法准确校正,因此对其准确性有严重的考虑.此外,在Linux中处理这个问题的代码的复杂性暗示着相信它实际上很难做到正确.这是特别的,但不仅仅是由Linux应该运行的大量硬件平台引起的.

结果: gettimeofday()以微秒粒度返回单调时间,但它提供的时间几乎从不one microsecond与任何其他时间源相比.

amd*_*mdn 19

gettimeofday()的微秒分辨率/粒度是如何完成的?

Linux在许多不同的硬件平台上运行,因此具体细节不同.在现代的x86平台上,Linux使用时间戳计数器,也称为TSC,它由多个运行在133.33 MHz的晶体振荡器驱动.晶体振荡器为处理器提供一个参考时钟,处理器将它乘以一些倍数 - 例如在2.93 GHz处理器上,倍数为22. TSC历史上,这是一个不可靠的时间源,因为当处理器运行时,实现会停止计数器睡觉,或者因为处理器移动乘数以改变性能状态或者当它变热时减速,因此倍数不是恒定的.现代x86处理器提供了一个TSC这是恒定的,不变的,不停的.在这些处理器上,它TSC是一个出色的高分辨率时钟,Linux内核确定启动时的初始近似频率.该TSC规定有gettimeofday()系统调用和纳秒分辨率为clock_gettime()系统调用微秒的分辨率.

这种同步是如何完成的?

你的第一个问题是关于Linux时钟如何提供高分辨率,第二个问题是关于同步,这是精度和准确度之间的区别.大多数系统都有一个由电池备份的时钟,以便在系统断电时保持时间.正如您可能期望的那样,这个时钟不具有高精度或高精度,但它会在系统启动时获得"在球场中"的时间.为了获得准确性,大多数系统使用可选组件从网络上的外部源获取时间.两个常见的是

  1. 网络时间协议
  2. 精确时间协议

这些协议定义网络上的主时钟(或由原子钟提供的时钟层),然后测量网络延迟以估计主时钟的偏移.一旦确定了与主设备的偏移,系统时钟就是disciplined保持准确.这可以通过

  1. 踩时钟(一个相对较大的,突然的,不经常的时间调整),或
  2. Slewing 时钟(定义为在给定时间段内通过缓慢增加或减少频率来调整时钟频率的程度)

内核提供adjtimex系统调用以允许时钟约束.有关现代英特尔多核处理器如何保持核心之间TSC同步的详细信息,请参阅CPU TSC提取操作,尤其是在多核多处理器环境中.

用于时钟调整的相关内核源文件是kernel/time.ckernel/time/timekeeping.c.