在Linux中,getrusage(RUSAGE_THREAD,...)和clock_gettime(CLOCK_THREAD_CPUTIME_ID,...)有什么区别?

Pat*_*yle 5 linux multithreading real-time

这个问题几乎说明了一切。根据的手册页getrusage(),它返回:

           struct timeval ru_utime; /* user CPU time used */
           struct timeval ru_stime; /* system CPU time used */
Run Code Online (Sandbox Code Playgroud)

根据的手册页clock_gettime(),它返回:

   CLOCK_THREAD_CPUTIME_ID (since Linux 2.6.12)
          Thread-specific CPU-time clock.
Run Code Online (Sandbox Code Playgroud)

那么,(特定于线程的)“使用的用户/系统CPU时间”与特定于线程的CPU时间时钟有何不同?

显然,我之所以问是因为,在从自定义RTOS移植到Linux的应用程序中,我看到了两者之间的差异。该应用程序具有通过tick()tock()功能实现的内部配置文件功能。我一直在研究这个问题,因此我将应用程序的一部分退化为:

tick()
// code commented out
tock()
Run Code Online (Sandbox Code Playgroud)

tick()函数记录运行时间,tock()函数记录运行时间,计算两者之间的增量,并报告该增量。当我实现tick()tock()使用时getrusage(),我得到的大部分为0,偶尔会有1000us或10000us的值(根据我是否将内核配置为1kHz或100Hz操作)。当我实现tick()tock()使用时clock_gettime(),我得到的值以13us为中心(偶尔会出现75us或100us的奇异偏移,但稍后再讨论)。

我尝试在内核和VIRT_CPU_ACCOUNTINGand / or的各种组合中启用高分辨率计时器VIRT_CPU_ACCOUNTING_GEN。我看到的唯一效果是,报告的非零值getrusage()从1000us更改为以1000us为中心的更高精度的范围。

我最终转而使用clock_gettime()并获得了更可信的结果,但是我想知道为什么这两个系统调用存在,以及为什么它们的行为如此不同。所以我想我应该问一些专家。

Arm*_*ali 2

\n

Linux 中的 getrusage(RUSAGE_THREAD, \xe2\x80\xa6) 和 \n Clock_gettime(CLOCK_THREAD_CPUTIME_ID,\xe2\x80\xa6) 有什么区别?

\n
\n\n

clock_gettime(CLOCK_THREAD_CPUTIME_ID, \xe2\x80\xa6)最终调用task_sched_runtime(p),它从 处获取计算的运行时间p->se.sum_exec_runtime,其中struct task_struct *pcurrent

\n\n

getrusage(RUSAGE_THREAD, \xe2\x80\xa6)调用task_cputime_adjusted(current, &utime, &stime),存在两个定义[a][b];使用哪一个取决于Linux内核配置项CONFIG_VIRT_CPU_ACCOUNTING_NATIVE

\n\n
\n

选择此选项可以启用更准确的任务和 CPU 时间统计。

\n
\n\n

现在我们需要知道您的内核中是否选择了此选项。无论如何,这两种情况看起来都与 所使用的方法不同clock_gettime()

\n\n

也就是说,我无法重现您的发现(我从两个系统调用中得到几乎相同的数字)。一个示例程序可以提供更多帮助。

\n\n
\n

所以我想我应该请教一些专家。

\n
\n\n

我认为您可以在 Linux 内核邮件列表上找到真正的专家。

\n