我正在寻找系统调用方面的一些清晰度。我尝试通过直接调用系统调用来避免 vDSO clock_gettime
。这是一个名为sys_clock_gettime
.
int clock = CLOCK_MONOTONIC;
struct timespec ts;
if (syscall(__NR_clock_gettime, clock, &ts) == -1){
exit(-1);
}
该程序采用时钟的名称(CLOCK_BOOTTIME, CLOCK_MONOTONIC
等...)和要进行的许多调用。例如,下面的代码片段将调用 100 次clock_gettime
时钟CLOCK_BOOTTIME
。
./sys_clock_gettime CLOCK_BOOTTIME 100
我试图ltrace
弄清楚发生了什么:
ltrace -cS ./sys_clock_gettime CLOCK_BOOTTIME 100
% time seconds usecs/call calls function
------ ----------- ----------- --------- --------------------
77.41 0.006887 68 100 syscall
14.32 0.001274 12 100 clock_gettime
1.79 0.000159 159 1 brk
1.17 0.000104 104 1 exit
1.16 0.000103 51 2 strcmp
0.82 0.000073 14 5 mmap
0.65 0.000058 14 4 mprotect
0.61 0.000054 54 1 exit_group
0.51 0.000045 45 1 atoi
0.31 0.000028 14 2 openat
0.30 0.000027 13 2 fstat
0.29 0.000026 13 2 close
0.19 0.000017 17 1 munmap
0.17 0.000015 15 1 access
0.16 0.000014 14 1 read
0.15 0.000013 13 1 arch_prctl
------ ----------- ----------- --------- --------------------
100.00 0.008897 225 total
出于某种原因,有一个syscall
条目和一个clock_gettime
条目。您可以说这syscall
是一个库条目,clock_gettime
而是一个系统调用条目,因为如果您禁用其中的-S
模式,ltrace
它将不会显示。如果我对系统调用的执行时间感兴趣,我应该添加syscall
和clock_gettime
信息吗?出于某种原因,这只发生在我在 Amazon Linux 2 中运行它时,在我自己的计算机上的 Ubuntu VM 中运行时,我只得到一个SYS_clock_gettime
条目,正如我所期望的那样。
现在,将它与另一个程序进行比较,我们称之为它vdso_clock_gettime
,它采用相同的参数。
ltrace -cS ./vdso_clock_gettime CLOCK_BOOTTIME 100
% time seconds usecs/call calls function
------ ----------- ----------- --------- --------------------
85.82 0.004340 43 100 clock_gettime
3.08 0.000156 156 1 brk
2.02 0.000102 51 2 strcmp
1.90 0.000096 96 1 exit
1.38 0.000070 14 5 mmap
1.13 0.000057 14 4 mprotect
0.97 0.000049 49 1 exit_group
0.93 0.000047 47 1 atoi
0.59 0.000030 15 2 openat
0.51 0.000026 13 2 fstat
0.51 0.000026 13 2 close
0.32 0.000016 16 1 access
0.32 0.000016 16 1 munmap
0.26 0.000013 13 1 read
0.26 0.000013 13 1 arch_prctl
------ ----------- ----------- --------- --------------------
100.00 0.005057 125 total
如果我不从第一个程序的输出中添加syscall
和clock_gettime
条目,那么调用系统调用所需的总时间clock_gettime
(12 微秒/调用)实际上比我在第二个中调用 vDSO 版本(43 微秒/调用)时要低程序。在我看来,这没有任何意义。只有当第一个程序的调用需要大约 80 微秒/调用(添加两个条目)时才有意义,因为 vDSO 应该加速这一点。
我知道在这个系统(内核 5.10)中,clock_gettime
是通过 vDSO 加速的,因为当我运行下面的代码片段时,我没有得到任何输出:
strace -e clock_gettime,gettimeofday -- date >/dev/null
+++ exited with 0 +++
我不确定这是否相关,但时钟源设置为tsc
. 关于这里发生了什么的任何想法?
编辑:查看实际跟踪,我开始认为调用syscall
包括两者。
syscall(228, 7, 0x7ffd270f9c80, 0x1999999999999999 <unfinished ...>
clock_gettime@SYS(7, 0x7ffd270f9c80, 0x1999999999999999, 0x7ffd270fa70a) = 0
<... syscall resumed> )
我也尝试过nanosleep
,如果我同时计算syscall
和nanosleep
调用,睡眠时间会加倍,这没有任何意义。我对么?