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

时间:2012-11-05 11:00:04

标签: linux time linux-kernel

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

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

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

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

编辑:根据我在amdn提供的链接中所读到的内容,特别是以下Intel链接,我会在此处添加一个问题:

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


编辑2:总结amdns answer并获得更多阅读结果:

Linux仅在启动时使用实时时钟(RTC) 与更高分辨率的计数器同步,例如。 Timestampcounter(TSC)。引导gettimeofday()之后返回的时间完全基于TSC值和此计数器的频率。通过将系统时间与外部时间源进行比较来校正/校准TSC frequency的初始值。调整由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  */

可以在Linux/kernel/time/timekeeping.c中找到。这表明可能会有 是一个更高分辨率的功能,可在以后的某个时间点使用。现在getnstimeofday()仅在内核空间中可用。

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

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

2 个答案:

答案 0 :(得分:19)

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

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

如何完成此同步?

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

  1. Network Time Protocol
  2. Precision Time Protocol
  3. 这些协议定义网络上的主时钟(或由原子钟提供的时钟层),然后测量网络延迟以估计主时钟的偏移。确定与主站的偏移后,系统时钟为disciplined以保持准确。这可以通过

    来完成
    1. 踩着时钟(一个相对较大的,突然的,不经常的时间调整)或
    2. Slewing时钟(定义为通过在给定时间段内缓慢增加或减少频率来调整时钟频率的程度)
    3. 内核提供adjtimex system call以允许时钟约束。有关现代英特尔多核处理器如何在核心之间保持TSC同步的详细信息,请参阅CPU TSC fetch operation especially in multicore-multi-processor environment

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

答案 1 :(得分:0)

Linux启动时,它使用硬件时钟初始化软件时钟。请参阅How Linux Keeps Track of Time中的Clock HOWTO一章。