Linux内核中的定时/时钟

时间:2018-10-02 20:55:16

标签: c linux linux-kernel

我正在编写一个设备驱动程序,并希望对一些代码进行基准测试,以了解可能遇到的瓶颈。因此,我想对一些代码段进行计时。

在用户空间中,我习惯将clock_gettime()CLOCK_MONOTONIC一起使用。查看内核源代码(请注意,我正在运行内核4.4,但最终将进行升级),看来我有几种选择:

  • getnstimeofday()
  • getrawmonotonic()
  • get_monotonic_coarse()
  • getboottime()

为方便起见,我编写了一个函数(请参见下文)以获取当前时间。我目前正在使用getrawmonotonic(),因为我知道这就是我想要的。我的函数以ktime_t的形式返回当前时间,因此我可以使用ktime_sub()来获取两次之间的经过时间。

static ktime_t get_time_now(void) {
   struct timespec time_now;
   getrawmonotonic(&time_now);
   return timespec_to_ktime(time_now);
}

鉴于可用的高分辨率时钟功能(jiffies对我不起作用),对于给定的应用程序,最佳功能是什么?一般来说,我对有关这些功能和基础时钟的任何/所有文档都感兴趣。首先,我很好奇时钟是否受到任何时序调整的影响以及它们的时期。

1 个答案:

答案 0 :(得分:5)

您是否将内核中进行的测量与用户空间中进行的测量直接进行比较?我想知道您是否选择使用CLOCK_MONOTONIC_RAW作为内核中的时基,因为您选择在用户空间中使用CLOCK_MONOTONIC。如果您要在内核中寻找一个返回时间CLOCK_MONOTONIC(而不是CLOCK_MONOTONIC_RAW(而不是ktime_get_ts())的类似且粗略的函数,请查看Documentation/timers/timekeeping.txt

您可能还可以使用原始内核滴答来测量要测量的内容(而不是代表多个内核滴答的jiffies),但是我不知道该怎么做

通常,如果您要查找有关Linux计时的文档,可以查看time/。通常,当我尝试弄清楚内核计时时,很不幸地,我也花了大量时间阅读time/timekeeping.c中的内核源代码(CLOCK_REALTIME是您现在想使用的大多数功能所在的地方...注释不是很好,但是您可以花一点时间将头缠在它上面。而且,如果您在学习后感到无私,请记住更新文档是对内核做出贡献的好方法:)

最后向您提出的问题是,时钟如何受到时序调整的影响以及使用了哪些纪元:

ntpd总是从1970年1月1日午夜开始(俗称Unix Epoch),如果不存在RTC或用户空间中的应用程序尚未设置RTC(或者我猜是内核模块(如果您想变得很奇怪)。通常设置它的用户空间应用程序是ntp守护程序chronyCLOCK_MONTONIC或类似的程序。它的值表示自1970年以来经过的秒数。

CLOCK_MONOTONIC代表自设备启动以来经过的秒数,如果设备以x的{​​{1}}值挂起,则恢复后,它将恢复为{也将{1}}设置为CLOCK_MONOTONIC。古代内核不支持。

x类似于CLOCK_BOOTTIME,但是在暂停/恢复期间增加了时间-因此,如果您以CLOCK_MONOTONIC的{​​{1}}值暂停5秒钟,您将返回CLOCK_BOOTTIME的{​​{1}}值。旧内核不支持该功能(它的支持来自x之后。)

完整的NTP守护程序(不是SNTP守护程序-这是一种更轻便且创建精度较低的协议),使用CLOCK_BOOTTIME进行大调整(“步骤”)来设置系统时钟或x+5或“跳跃”)–这些会立即影响CLOCK_MONOTONIC的总价值,并使用CLOCK_REALTIME进行较小的调整(“倾斜”或“倾斜”)–这些会影响{{1 }}每个CPU时钟周期向前移动。我认为对于某些体系结构,您实际上可以通过某种方式来调整CPU时钟周期,并且内核在可能的情况下以这种方式实现settimeofday(),但请不要在此引用我的观点。从内核的大部分角度和用户空间的角度来看,这实际上都没有关系。

CLOCK_REALTIMEadjtime()和所有其他朋友以与CLOCK_REALTIME相同的速率回转,这在大多数情况下实际上非常方便。它们不受adjtime()中步骤的影响,仅受转换的影响。

CLOCK_MONOTONICCLOCK_BOOTTIME和朋友摆摆的速率与CLOCK_REALTIMECLOCK_REALTIMECLOCK_MONOTONIC_RAW相同。我想有时候这很有用。

Linux向用户空间(CLOCK_BOOTTIME_RAWCLOCK_REALTIME)提供了一些特定于进程/线程的时钟,我一无所知。我不知道它们是否可以在内核中轻松访问。