如何解释时间“真实”、“用户”和“系统”

Win*_*nix 3 bash benchmarks

介绍

我一直在微调代码,以将 bash 程序各个部分的处理时间从 30 秒减少到不到一秒。我无法思考time命令在报告real,usersys变量时如何工作。

我有这个代码:

echo " "
echo "Time to build DirsNdxArr from DirsArr $DirsArrCnt elements:"
DirsArrCnt=${#DirsArr[@]}
time for (( i=1; i<$DirsArrCnt; i=i+$DaElementCnt )); do
    DirsNdxArr["${DirsArr[$i]}"]=$i
    AllItemSizes=$(( $AllItemSizes + ${DirsArr[$(( $i + $ColFileSizes - 1 ))]} ))
done

echo " "
echo "Time to build FilesNdxArr from FilesArr $FilesArrCnt elements:"
FilesArrCnt=${#FilesArr[@]}
time for (( i=0; i<$FilesArrCnt; i=i+$FaElementCnt )); do
    FilesNdxArr["${FilesArr[$i]}"]=$i
    AllTagSizes=$(( $AllTagSizes + ${FilesArr[$(( $i + $FaColFileSizes ))]} ))
done
Run Code Online (Sandbox Code Playgroud)

报告如下:

Time to build DirsNdxArr from DirsArr 56700 elements:

real    0m0.149s
user    0m0.149s
sys     0m0.000s

Time to build FilesNdxArr from FilesArr 390 elements:

real    0m0.002s
user    0m0.002s
sys     0m0.000s
Run Code Online (Sandbox Code Playgroud)

为什么sys时间报告为零?

解释time内置命令的输出会假设系统什么都不做,但这肯定不是正在发生的事情?

PS我知道,\n可作为一个新行echo-e参数。我的习惯是为了可读性而牺牲一种线性可爱和边缘论点。

Ser*_*nyy 5

长话短说,这只是意味着您的程序没有请求执行任何特权任务,因此 CPU 没有在特权(内核)模式下花费时间。

基础第一

首先,为了time正确解释输出,您需要了解几件事:

  • time您正在运行哪个命令(因为有多个)
  • 每个字段的含义以及每个字段的含义(此处额外阅读)
  • 内核态和用户态的区别

有两种类型的time命令。有内置的外壳,有/usr/bin/time. 内置的 shell 是您正在使用的 shell,它默认显示 3 行realuser、 和sys。手册time还提到了这种相同形式的输出:

 -p, --portability
     Use the following format string, for conformance with POSIX standard 1003.2:
               real %e
               user %U
               sys %S
Run Code Online (Sandbox Code Playgroud)

如果你检查“格式化输出”部分,我们有:

         E      Elapsed real (wall clock) time used by the process, in [hours:]minutes:seconds.
         U      Total number of CPU-seconds that the process used directly (in user mode), in seconds.
         S      Total number of CPU-seconds used by the system on behalf of the process (in kernel mode), in
                 seconds.
Run Code Online (Sandbox Code Playgroud)

从所有这些信息中,我们可以得出 CPU 可以运行的两种模式 - 用户模式和内核模式,该time命令显示 CPU 保持在给定模式下的时间,以执行您的程序/应用程序要求 CPU 执行的任何操作。

了解什么是系统时间报告以及 0 值意味着什么

好的,所以我们理解区别在于代码可以运行的用户模式和内核模式。我们已经可以认为这基本上意味着程序没有使用内核模式来执行某些任务。这实际上意味着什么?

参考这篇文章

在内核模式下,执行代码可以完全且不受限制地访问底层硬件。它可以执行任何 CPU 指令并引用任何内存地址。

来自同一帖子的另一个答案:

从用户模式到内核模式的切换不是由 CPU 自动完成的。CPU 被中断(定时器、键盘、I/O)中断。当中断发生时,CPU 停止执行当前运行的程序,切换到内核模式,执行中断处理程序。此处理程序保存 CPU 的状态,执行其操作,恢复状态并返回到用户模式。

所以这就是你的输出的意思 - 没有切换到内核模式,CPU 没有从程序接收到任何中断来这样做。这也意味着您的代码没有任何需要 CPU 提升权限的内容

注意:这可能应该改写为“没有长时间/明显的切换到内核模式”,因为malloc()在 C 中使用类似函数的东西分配内存需要切换到内核模式,但这些是微观切换,我们真的必须这样做使用调试器或strace命令进行调查。