为什么 Linux utils 不使用系统调用来获取当前时间?

为什么 Linux utils 不使用系统调用来获取当前时间?

我真的很想理解为什么我们的来宾虚拟机没有“像他们应该的那样”使用 kvm-clock 驱动程序。他们运行的是 RHEL 7.2、glibc-2.17、kern 3.10.0。诸如date和 之类的程序perl -e 'print time'获取当前时间,但无需进行系统调用。这通过 strace 和 ltrace 得到了证实,并通过使用 gdb 和通过汇编进行跟踪进一步证实了这一点,该汇编绕过了syscall并执行了一些名为 的指令rtdscp

这是 glibc 作者的优化尝试吗?有什么方法可以禁用此功能并强制 glibc 调用进行系统调用(缺少 LD_PRELOAD 黑客)?

更新2016年10月14日:

回顾了最新的POSIX 草案,部分答案是明确的:有一种方法可以向 CPU 请求时钟,但 GNU glibc 错误地将这种实现强加给其用户。解决方法是直接调用系统调用。 (嘘)

如果定义了_POSIX_CPUTIME,实现应支持通过调用clock_getcpuclockid()获得的时钟ID值,它代表给定进程的CPU时间时钟。实现还应支持特殊的clockid_t值CLOCK_PROCESS_CPUTIME_ID,它表示调用时钟之一时调用进程的CPU时间时钟() 或计时器_() 功能。

鉴于用户可以 是否有任何真正的论据反对“如果clock_id设置为CLOCK_REALTIME,则应使用系统调用”的概念?

答案1

我认为你没有看到系统调用发生的原因是一些 Linux 系统调用(特别是那些与时间相关的,比如gettimeofday(2)time(2))通过虚拟DSO,其中包含一些系统调用的优化实现:

“vDSO”(虚拟动态共享对象)是一个小型共享库,内核自动将其映射到所有用户空间应用程序的地址空间。

内核提供的一些系统调用最终会被用户空间代码频繁使用,以至于此类调用可以主导整体性能。这是由于调用的频率以及退出用户空间和进入内核导致的上下文切换开销造成的。

现在,手册提到所需的信息只是放置在内存中,以便进程可以直接访问它(毕竟当前时间并不是什么秘密)。我不知道具体的实现,只能猜测CPU时间戳计数器在其中的作用。

所以,实际上并不是 glibc 在做优化,而是内核在做优化。可以通过设置vdso=0来禁用它内核命令行,并且应该可以编译出来。然而,我找不到是否可以在 glibc 端禁用它(至少在不修补库的情况下)。

还有很多关于此的其他信息和来源关于SE的问题


你在问题中说:

在审查了最新的 POSIX 草案后,部分答案已经明确:有一种方法可以向 CPU 请求时钟,但 GNU glibc 错误地将这种实现强加给了用户。

我认为这是一个相当大胆的声明。我没有看到任何证据表明“错误地强迫”用户做任何事情,至少不会对他们不利。当前系统上运行的几乎所有 Linux 进程都使用 vDSO 实现,这意味着如果它不能正常工作,人们就会听到一些非常响亮的抱怨。您还说收到的时间是正确的。

你从手册中给出的引文clock_gettime似乎只提到调用必须支持由clock_getcpuclockidCLOCK_REALTIME,与或 的行为无关gettimeofday

相关内容