$ time foo
real 0m0.003s
user 0m0.000s
sys 0m0.004s
$
“真实”,“用户” 和 “系统” 在时间输出中意味着什么?
在对我的应用进行基准测试时哪一个有意义?
Real,User 和 Sys 处理时间统计信息
其中一件事与另一件事情不同。实际是指实际经过的时间; User 和 Sys 指的是仅由进程使用的 CPU 时间。
真实是挂钟时间 - 从通话开始到结束的时间。这是所有经过的时间,包括其他进程使用的时间片和进程花费的时间(例如,如果它等待 I / O 完成)。
用户是进程内用户模式代码(内核外)花费的 CPU 时间。这只是执行过程时使用的实际 CPU 时间。流程花费的其他流程和时间不计入此数字。
Sys是进程内核中花费的 CPU 时间。这意味着执行内核中系统调用所花费的 CPU 时间,而不是仍在用户空间中运行的库代码。与'user' 一样,这只是进程使用的 CPU 时间。有关内核模式(也称为 “管理程序” 模式)和系统调用机制的简要说明,请参见下文。
User+Sys
将告诉您进程使用的实际 CPU 时间。请注意,这是跨所有 CPU 的,因此如果进程有多个线程(并且此进程在具有多个处理器的计算机上运行),则可能会超过Real
报告的挂钟时间(通常会发生)。请注意,在输出中,这些数字包括所有子进程(及其后代)的User
和Sys
时间,以及它们可以被收集的时间,例如wait(2)
或waitpid(2)
,尽管底层系统调用返回流程及其子项的统计信息。
按time (1)
报告的统计数据的来源time (1)
按time
报告的统计信息是从各种系统调用中收集的。 “用户” 和 “系统” 来自wait (2)
( POSIX )或times (2)
( POSIX ),具体取决于特定系统。 'Real' 是根据gettimeofday (2)
调用收集的开始和结束时间计算的。根据系统的版本,还可以按time
收集各种其他统计数据,例如上下文切换的数量。
在多处理器计算机上,多线程进程或分叉子进程的进程可能会比 CPU 总时间小 - 因为不同的线程或进程可能并行运行。此外,报告的时间统计来自不同的来源,因此对于非常短的运行任务记录的时间可能受到舍入误差的影响,如原始海报给出的示例所示。
关于内核与用户模式的简要介绍
在 Unix 或任何受保护的内存操作系统上, “内核” 或 “超级用户”模式是指 CPU 可以操作的特权模式 。某些可能影响安全性或稳定性的特权操作只能在 CPU 运行时完成这种模式; 这些操作不适用于应用程序代码。这种动作的一个例子可能是操纵MMU以获得对另一个进程的地址空间的访问。通常, 用户模式代码不能这样做(有充分理由),尽管它可以从内核请求共享内存 ,这可以由多个进程读取或写入。在这种情况下,通过安全机制从内核显式请求共享内存,并且两个进程必须显式附加到它才能使用它。
特权模式通常称为 “内核” 模式,因为内核由在此模式下运行的 CPU 执行。为了切换到内核模式,您必须发出一个特定的指令(通常称为陷阱 ),它将 CPU 切换到以内核模式运行, 并从跳转表中保存的特定位置运行代码。出于安全原因,您无法切换到内核模式并执行任意代码 - 陷阱通过无法写入的地址表进行管理,除非 CPU 以管理员模式运行。使用显式陷阱编号进行陷阱,并在跳转表中查找地址; 内核具有有限数量的受控入口点。
C 库中的 “系统” 调用(特别是手册页第 2 节中描述的那些)具有用户模式组件,这是您实际从 C 程序调用的组件。在幕后,他们可以向内核发出一个或多个系统调用来执行特定服务(如 I / O),但是他们仍然可以在用户模式下运行代码。如果需要,也可以从任何用户空间代码直接向内核模式发出陷阱,尽管您可能需要编写汇编语言片段来为调用正确设置寄存器。可以在此处找到描述 Linux 内核提供的系统调用的页面以及设置寄存器的约定。
关于'sys' 的更多信息
您的代码无法通过用户模式执行某些操作 - 例如分配内存或访问硬件(HDD,网络等)。这些都在内核的监督下,只有它才能做到。您执行的某些操作(如malloc
或fread
/ fwrite
)将调用这些内核函数,然后将计为 “sys” 时间。不幸的是,它并不像 “每次调用 malloc 都会计入'sys'时间” 那么简单。对malloc
的调用将自己进行一些处理(仍然计入 '用户' 时间),然后在它可能调用内核函数的某个地方(在'sys' 时间内计算)。从内核调用返回后,'user' 中会有更多时间,然后malloc
将返回到您的代码。至于何时发生切换,以及在内核模式下花费了多少...... 你不能说。这取决于库的实现。此外,其他看似无辜的函数也可能在后台使用malloc
等,这将在'sys' 中再次有一些时间。
为了扩展已接受的答案 ,我只是想提供real
≠ user
+ sys
另一个原因。
请记住, real
表示实际经过的时间,而user
和sys
值表示 CPU 执行时间。因此,在多核系统上, user
和 / 或sys
时间(以及它们的总和)实际上可能超过实时。例如,在我正在为类运行的 Java 应用程序中,我得到以下值:
real 1m47.363s
user 2m41.318s
sys 0m4.013s
• real :从开始到结束运行过程所花费的实际时间,就好像是由带有秒表的人测量的
• user :计算期间所有 CPU 花费的累计时间
• sys :所有 CPU 在系统相关任务(如内存分配)期间所累积的时间。
请注意,有时 user + sys 可能大于 real,因为多个处理器可能并行工作。