介绍
我一直在微调代码,以将 bash 程序各个部分的处理时间从 30 秒缩短到 1 秒以下。我无法理解命令time
在报告real
、user
和sys
变量时是如何工作的。
我有这个代码:
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
报告如下:
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
为何sys
时间报告为零?
解释内置命令的输出时,time
人们会认为系统没有执行任何操作,但这肯定不是正在发生的事情?
附言我知道\n
可以用作带echo
参数的-e
换行符。我的习惯是牺牲一行代码的可爱和边缘论点来提高可读性。
答案1
长话短说,它只是意味着您的程序没有请求执行任何特权任务,因此 CPU 没有在特权(内核)模式下花费任何时间。
基础第一
首先,为了time
正确解释输出,您需要了解几件事:
- 你正在运行哪个
time
命令(因为有多个) - 每个字段的含义以及每个字段的含义(额外阅读这里)
- 内核模式和用户模式的区别
命令有两种类型time
。一种是内置 shell,另一种是/usr/bin/time
。内置 shell 是你正在使用的 shell,它默认显示 3 行,real
、user
和sys
。 的手册time
也提到了这种相同的输出形式:
-p, --portability Use the following format string, for conformance with POSIX standard 1003.2: real %e user %U sys %S
如果你检查“格式化输出”部分,我们有:
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.
从所有这些信息中,我们可以得知 CPU 可以运行两种模式 - 用户模式和内核模式,并且该time
命令显示 CPU 在给定模式下保持多长时间来执行程序/应用程序要求 CPU 执行的操作。
了解什么是系统时间报告以及 0 值的含义
好的,我们明白了区别在于代码可以在用户模式和内核模式下运行。我们已经可以理解,这基本上意味着程序没有使用内核模式来执行某些任务。这实际上意味着什么?
參閱这个帖子:
在内核模式下,执行代码可以完全、不受限制地访问底层硬件。它可以执行任何 CPU 指令并引用任何内存地址。
来自同一篇文章的另一个回答:
从用户模式切换到内核模式不是由 CPU 自动完成的。CPU 被中断(定时器、键盘、I/O)打断。当发生中断时,CPU 停止执行当前正在运行的程序,切换到内核模式,执行中断处理程序。该处理程序保存 CPU 的状态,执行其操作,恢复状态并返回到用户模式。
所以这就是你的输出的意思——没有切换到内核模式,CPU 没有收到程序的任何中断。这也意味着你的代码没有任何需要从 CPU 提升权限的东西
笔记:这可能应该改写为“没有长时间/明显的切换到内核模式”,因为使用malloc()
C 中的函数之类的东西分配内存需要切换到内核模式,但这些是微观的切换,我们实际上必须使用调试器或命令来调查strace
。