我正在编写一个设备驱动程序,并希望对一些代码进行基准测试,以了解可能遇到的瓶颈。因此,我想对一些代码段进行计时。
在用户空间中,我习惯将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对我不起作用),对于给定的应用程序,最佳功能是什么?一般来说,我对有关这些功能和基础时钟的任何/所有文档都感兴趣。首先,我很好奇时钟是否受到任何时序调整的影响以及它们的时期。
答案 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守护程序chrony
或CLOCK_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_REALTIME
,adjtime()
和所有其他朋友以与CLOCK_REALTIME
相同的速率回转,这在大多数情况下实际上非常方便。它们不受adjtime()
中步骤的影响,仅受转换的影响。
CLOCK_MONOTONIC
,CLOCK_BOOTTIME
和朋友摆摆的速率与CLOCK_REALTIME
,CLOCK_REALTIME
和CLOCK_MONOTONIC_RAW
相同。我想有时候这很有用。
Linux向用户空间(CLOCK_BOOTTIME_RAW
,CLOCK_REALTIME
)提供了一些特定于进程/线程的时钟,我一无所知。我不知道它们是否可以在内核中轻松访问。