[英]Timing/Clocks in the Linux Kernel
我正在编写一个设备驱动程序,并希望对几段代码进行基准测试,以便了解我可能遇到的一些瓶颈问题。 因此,我想计算几段代码。
在用户空间中,我习惯使用带有CLOCK_MONOTONIC
clock_gettime()
。 查看内核源代码(请注意我运行的是内核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对我来说不起作用),我给定的应用程序的最佳功能是什么? 更一般地说,我对任何/所有关于这些函数和基础时钟的文档感兴趣。 首先,我很好奇时钟是否受到任何时序调整及其时代的影响。
您是否正在将您在内核中进行的测量直接与您在用户空间中进行的测量进行比较? 我想知道您选择使用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 Epoch)开始,如果没有RTC存在或者它还没有被用户空间中的应用程序设置(或者我想如果你想成为内核模块)奇怪的)。 通常,设置它的用户空间应用程序是ntp守护程序, ntpd
或chrony
或类似的。 它的值代表自1970年以来经过的秒数。
CLOCK_MONTONIC
表示自设备启动以来经过的秒数,如果设备在CLOCK_MONOTONIC
值为x
时暂停,当它恢复时,它将恢复,同时CLOCK_MONOTONIC
设置为x
。 它在古代内核上不受支持。
CLOCK_BOOTTIME
类似于CLOCK_MONOTONIC
,但是在暂停/恢复时有时间添加到它 - 所以如果你暂停在CLOCK_BOOTTIME
值x
,持续5秒,你将返回CLOCK_BOOTTIME
值为x+5
。 旧内核不支持它(它的支持是在CLOCK_MONOTONIC
之后CLOCK_MONOTONIC
)。
完全充实的NTP守护进程(不是SNTP守护进程 - 这是一个更轻量级,创建精度更低的协议)使用settimeofday()
进行大调整(“步骤”或“跳转”)设置系统时钟或CLOCK_REALTIME
- 这些立即影响CLOCK_REALTIME
,并使用adjtime()
进行较小的调整(“回转”或“倾斜”) - 这些会影响CLOCK_REALTIME
每CPU时钟周期向前移动的速率。 我认为对于某些体系结构,您实际上可以通过某种方式或其他方式调整CPU时钟周期,并且如果可能,内核以这种方式实现adjtime()
,但不要引用我的话。 从内核的大部分角度和用户空间的角度来看,它实际上并不重要。
CLOCK_MONOTONIC
, CLOCK_BOOTTIME
以及所有其他朋友以与CLOCK_REALTIME
相同的速率进行CLOCK_REALTIME
,这在大多数情况下实际上相当方便。 它们不受CLOCK_REALTIME
的步骤的CLOCK_REALTIME
,只有CLOCK_REALTIME
才会受到影响。
CLOCK_MONOTONIC_RAW
, CLOCK_BOOTTIME_RAW
和朋友不会以与CLOCK_REALTIME
, CLOCK_MONOTONIC
和CLOCK_BOOTIME
相同的速率进行转换。 我想这有时很有用。
Linux为用户空间提供了一些特定于进程/线程的时钟( CLOCK_PROCESS_CPUTIME_ID
, CLOCK_THREAD_CPUTIME_ID
),我对此一无所知。 我不知道它们是否可以在内核中轻松访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.