【问题标题】:Use of _COARSE variants in clock_gettime() still calls sys_clock_gettime() system call在clock_gettime() 中使用_COARSE 变体仍会调用sys_clock_gettime() 系统调用
【发布时间】:2014-10-02 09:22:17
【问题描述】:

我一直在使用 clock_gettime 函数和 CLOCK_MONOTONIC_COARSE 作为我的代码中的第一个参数,如下所示:

    struct timespec tmptv;
    clock_gettime(CLOCK_MONOTONIC_COARSE, &tmptv);

但是,当我在我的代码上运行 gperftools cpu profiler 时,我收到的 __sys_clock_gettime 调用百分比相对较高,约为 8.6%。

我使用clock_getres() 函数检查了我对CLOCK_MONOTONIC_COARSE 的使用,它显示了4000000 ns 的分辨率,我认为这是1 ms 的正确数量级。

我是否想在我的代码中包含除 time.h 之外的另一个库,让我在不进行系统调用的情况下使用 CLOCK_MONOTONIC_COARSE?我想避免这种低效率。

谢谢!

【问题讨论】:

    标签: c++ linux performance time profiling


    【解决方案1】:

    看起来它仍然应该是一个系统调用,如果这个补丁可以通过: http://lwn.net/Articles/342018/

    它只是不调用特定函数来从某些硬件寄存器中获取确切的时间,至少在某些硬件上,这非常慢。

    但是有很多因素:

    它是什么硬件? clock_gettime() 应该是 x86 和 x86-64 上的虚拟系统调用 [vsyscall]。

    最后,如果你在很多函数调用中把它称为“作为第一个参数”,那么很可能只是它需要多少时间。

    我怀疑是否有任何方法可以在没有虚拟系统调用的情况下获取当前时间,因为您确实需要来自内核的一些信息来获取当前时间 - 如果没有,它应该从哪里找到当前时间'不要对内核代码进行某种调用。

    虚拟系统调用通过向用户空间添加一点“内核代码”来工作,用户空间对内核内存空间的某些部分具有只读访问权限,特别是“当前进程 ID”和“父进程” ID”和某些类型的时间信息,例如我认为的“当前时间”和“CPU 使用情况统计”。这允许系统调用完全在用户空间中完成,因此比转换到内核模式并再次退出的“真实”系统调用要快得多。

    【讨论】:

    • 嗨,我明白了,这是有道理的。我在 x86-64 机器上工作,所以我想象带有 CLOCK_MONOTONIC 的 clock_gettime() 和带有 CLOCK_MONOTONIC_COARSE 的 clock_gettime() 都在我的机器上执行虚拟系统调用,导致当我从 CLOCK_MONOTONIC 切换到 CLOCK_MONOTONIC_COARSE 时 CPU 使用率没有减少.
    【解决方案2】:

    对于那些感兴趣的人,这里是所有这些clock_id的时间。

    在 corei7 gen7、内核 4.4、64 位上完成测量。

    以 100 分表示最快:

     100: CLOCK_REALTIME_COARSE and CLOCK_MONOTONIC_COARSE
     410: CLOCK_REALTIME and CLOCK_MONOTONIC
    5530: CLOCK_BOOTTIME
    6630: CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID
    

    所以我假设,从内核 4.4 开始,CLOCK_REALTIME、CLOCK_MONOTONIC 及其 COARSE 变体都使用 vdso。这可以通过 time -v 显示系统时间为零的事实得到证实,所有时间都花在用户空间中。 COARSE 变体只是一种以牺牲精度为代价的优化。

    另一个clock_id 可能没有使用vdso 并进行真正的系统调用。系统时间占总时间的很大一部分这一事实证实了这一点。

    当然,如果在 vdso 中实现了更多的clock_id,这在后续内核中可能会有所不同。

    【讨论】:

      猜你喜欢
      • 2014-09-23
      • 1970-01-01
      • 2014-05-08
      • 2014-12-25
      • 2010-09-21
      • 1970-01-01
      • 2012-09-23
      • 2018-07-08
      • 1970-01-01
      相关资源
      最近更新 更多