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