在clock_gettime()中使用_COARSE变体仍然会调用sys_clock_gettime()系统调用

时间:2014-08-08 19:51:56

标签: c++ linux performance time profiling

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

    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中包含另一个库,除了time.h之外让我在不进行系统调用的情况下使用CLOCK_MONOTONIC_COARSE?我想避免这种低效率。

谢谢!

2 个答案:

答案 0 :(得分:1)

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

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

但是有很多因素:

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

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

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

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

答案 1 :(得分:0)

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

在corei7 gen7(内核4.4,64位)上完成的测量。

以100的比例表示最快的速度:

CLASSPATH=$APP_HOME/bin/jaxb_lib/activation.jar:$APP_HOME/bin/jaxb_lib/jaxb-impl.jar:$APP_HOME/bin/jaxb_lib/jaxb-xjc.jar:$APP_HOME/bin/jaxb_lib/jaxb-core.jar:$APP_HOME/bin/jaxb_lib/jaxb-jxc.jar:$APP_HOME/bin/jaxb_lib/jaxb-api.jar:<etc etc...DO NOT REMOVE THE OTHER JARS!...>

因此,我假定从内核4.4开始,CLOCK_REALTIME,CLOCK_MONOTONIC及其COARSE变体都使用vdso。时间-v表示系统时间为零,所有时间都用在用户空间中,这一事实得到了证实。 COARSE变体仅是优化,以牺牲精度为代价。

另一个clock_id可能未使用vdso并进行了真实的系统调用。系统时间在总时间中占很大比例,这一事实得到了证实。

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