Linux中的time命令显示的用户和系统时间不可能很高

时间:2014-03-10 08:44:58

标签: linux performance bash linux-kernel xargs

我在包含~7000个文件的目录中运行以下命令:

time find . | xargs -P8 -n1 grep -F 'xxx'

结果是:

real    0m1.638s
user    1m1.090s
sys     0m5.080s

我非常理解(user+cpu)可以是< or > cpuTime,但以下界限应该成立:

(user + sys) < real * NCPU

其中NCPU是系统上的逻辑核心数。在任何时刻,最多应运行NCPU进程,并分配用户或系统时间。然而,我有12个逻辑核心(6个真实核心x 2个超线程),但1.638 * 12 = ~20 seconds,但不知怎的,我的进程设法消耗了超过一分钟的CPU时间。

主观上1.6s实时是正确的(我在较大的目录上尝试过它)。

使用-P值进行混淆会改变报告的实际和系统时间,但它会在8-12附近的某个值附近保持稳定。

请注意,没有一个文件包含xxx,但如果我使用的字符串获得一些匹配,结果是相同的。

1 个答案:

答案 0 :(得分:1)

“用户”和“系统”时间记帐的最常见机制是基于Linux定期计时器。这种方法不准确,特别是对于短流程:

http://www.cs.rochester.edu/courses/252/spring2014/notes/XX_timing

  

内核使用常规定时器中断来触发上下文切换,   提供SIGALARM信号,跟踪时间(字面意思,通过计数   计时器滴答),安排簿记任务等。

     

内核保持每个进程计数多少次计时器   中断处理程序在(a)用户模式或(b)内核中找到它(进程)   (系统)模式。这些计数的工作方式类似于统计分析   gprof给你一个很好的感觉,平均很长一段时间,   进程运行的时间长度,以及进程的大部分时间   它花在内核(系统)上。 ...   因为统计抽样的粒度大致是   相当于一个调度量子(~5-20ms),间隔时间是   非常不准确的时间低于约100毫秒。即使超出这个范围,也是如此   只有10%左右才有好处。它也倾向于收取流程   处理定时器中断的一些开销。作者报告   在他们的Linux系统上,这会高估4-5%的消耗时间。

同样http://www.cs.toronto.edu/~demke/469F.06/Lectures/Lecture5.pdf幻灯片5,6,7“间隔计数的准确性”。

如果我们检查基本实现,我们知道“cpu”和“系统”时间在linux内核的kernel/timer.c文件中更新,在“update_process_times”中http://lxr.free-electrons.com/source/kernel/timer.c#L1349

1345 /*
1346  * Called from the timer interrupt handler to charge one tick to the current
1347  * process.  user_tick is 1 if the tick is user time, 0 for system.
1348  */
1349 void update_process_times(int user_tick)
1350 {
1351         struct task_struct *p = current;
1352         int cpu = smp_processor_id();
1353 
1354         /* Note: this timer irq context must be accounted for as well. */
1355         account_process_tick(p, user_tick);  // <<<<<<<<<<< here
1356         run_local_timers();
1357         rcu_check_callbacks(cpu, user_tick);
    ...
1362         scheduler_tick();
1363         run_posix_cpu_timers(p);
1364 }

tick_nohz_handlertick_sched_timer - &gt;调用“update_process_times” tick_sched_handlekernel/time/tick-sched.c#L147)和tick_handle_periodic - &gt; tick_periodickernel/time/tick-common.c#L90)。 我认为在某些情况下,update_process_times可能比定时器中断更频繁地调用。