您是否将直接在内核中进行的测量与在用户空间中进行的测量进行比较?我想知道您选择在内核中使用CLOCK_MONOTONIC_RAW 作为时基,因为您选择在用户空间中使用CLOCK_MONOTONIC。如果您正在内核中寻找一个类似且非粗略的函数,它返回CLOCK_MONOTONIC(而不是CLOCK_MONOTONIC_RAW)时间,请查看ktime_get_ts()。
您也可以使用原始内核刻度来测量您要测量的内容(而不是代表多个内核刻度的 jiffies),但我不知道该怎么做.
一般来说,如果您想查找有关 Linux 计时的文档,您可以查看 Documentation/timers/timekeeping.txt。通常,当我试图弄清楚内核计时时,不幸的是,我也只是花大量时间阅读time/ 中的内核源代码(time/timekeeping.c 是您现在正在考虑使用的大多数功能......不是很好的评论,但你可以花一点时间把你的头绕起来)。如果您在学习后感到无私,请记住更新文档是为内核做出贡献的好方法:)
最后关于时钟如何受时序调整影响以及使用哪些时期的问题:
CLOCK_REALTIME 总是从 1970 年 1 月 1 日午夜开始(俗称 Unix 纪元),如果不存在 RTC 或者它尚未由用户空间中的应用程序设置(或者我猜是内核模块如果你想变得奇怪)。通常设置这个的用户空间应用程序是 ntp 守护进程,ntpd 或 chrony 或类似的。它的值表示自 1970 年以来经过的秒数。
CLOCK_MONTONIC 表示自设备启动以来经过的秒数,如果设备在x 的CLOCK_MONOTONIC 值处挂起,当它恢复时,它会在CLOCK_MONOTONIC 设置为@987654336 的情况下恢复@也一样。古代内核不支持它。
CLOCK_BOOTTIME 类似于CLOCK_MONOTONIC,但在暂停/恢复期间添加了时间——因此,如果您在x 的CLOCK_BOOTTIME 值暂停5 秒,您将返回一个CLOCK_BOOTTIME 的值是 x+5。旧内核不支持它(它的支持是在 CLOCK_MONOTONIC 之后出现的)。
完整的 NTP 守护进程(不是 SNTP 守护进程——这是一个更轻量级且创建精度更低的协议)设置系统时钟,或CLOCK_REALTIME,使用settimeofday() 进行大调整(“步数”或“跳跃” ) -- 这些会立即影响CLOCK_REALTIME 的总值,并使用adjtime() 进行较小的调整(“回转”或“倾斜”)——这些会影响CLOCK_REALTIME 每个CPU 时钟周期向前移动的速率。我认为对于某些架构,您实际上可以通过某种方式调整 CPU 时钟周期,如果可能的话,内核会以这种方式实现adjtime(),但不要引用我的话。从内核的大部分角度和用户空间的角度来看,这实际上并不重要。
CLOCK_MONOTONIC、CLOCK_BOOTTIME 和所有其他朋友都以与CLOCK_REALTIME 相同的速度旋转,这在大多数情况下实际上是相当方便的。它们不受CLOCK_REALTIME 中步骤的影响,仅受 slews 影响。
CLOCK_MONOTONIC_RAW、CLOCK_BOOTTIME_RAW 和朋友不会以与CLOCK_REALTIME、CLOCK_MONOTONIC 和CLOCK_BOOTIME 相同的速度进行转换。我想这有时很有用。
Linux 为用户空间提供了一些进程/线程特定的时钟(CLOCK_PROCESS_CPUTIME_ID、CLOCK_THREAD_CPUTIME_ID),我对此一无所知。我不知道它们是否可以在内核中轻松访问。