为什么 strace 的 -c 和 -T 时间不一致?

Why do strace's timings for -c and -T disagree?

我有一个 rsync 运行 到网络挂载文件系统的空操作(所有文件都已经存在)目录复制操作。

因为所有文件都已经存在,rsync 唯一做的就是 lstat() 系统调用。

如果我strace -c这个,我得到这个:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.076780          30      2524           lstat
------ ----------- ----------- --------- --------- ----------------
100.00    0.076780                  2524           total

real    0m5.451s

但是如果我 strace -T(显示每个系统调用的时间),我得到这个:

lstat("file1", {st_mode=S_IFREG|0644, st_size=32820,   ...}) = 0 <0.005523>
lstat("file2", {st_mode=S_IFREG|0644, st_size=20816,   ...}) = 0 <0.001529>
lstat("file3", {st_mode=S_IFREG|0644, st_size=1828312, ...}) = 0 <0.001991>
lstat("file4", {st_mode=S_IFREG|0644, st_size=1823258, ...}) = 0 <0.001326>
lstat("file5", {st_mode=S_IFREG|0644, st_size=32820,   ...}) = 0 <0.006562>
lstat("file6", {st_mode=S_IFREG|0644, st_size=22578,   ...}) = 0 <0.002151>
lstat("file7", {st_mode=S_IFREG|0644, st_size=32835,   ...}) = 0 <0.001705>
lstat("file8", {st_mode=S_IFREG|0644, st_size=25493,   ...}) = 0 <0.001492>
lstat("file9", {st_mode=S_IFREG|0644, st_size=1783930, ...}) = 0 <0.001974>

时代完全不一样了!

-c 声称每个 lstat 大约需要 30 usecs/call,而 -T 显示大约 2 ms/call.

2 毫秒是有道理的,这是网络挂载的 ping 速度的顺序,但 30 微秒显然是不可能的。

为什么 usecs/call 列中的值是假的?我是不是误会了?

来自 strace 手册页:

-c Count time, calls, and errors for each system call and report a summary on program exit. On Linux, this attempts to show system time (CPU time spent running in the kernel) independent of wall clock time. If -c is used with -f or -F (below), only aggregate totals for all traced processes are kept.

(重点是我加的。)大多数 I/O 只会让实际的异步调用和上下文切换,而不是进行某种繁忙的循环。 -T 将改为显示调用内核与调用返回之间的挂钟持续时间。

编辑: 在以后的版本中,-w 给你等待时间,而不是系统时间,所以 -c -w 给你的时间应该匹配 -T.