ThinkFlow
ThinkFlow

Reputation: 171

Use of _COARSE variants in clock_gettime() still calls sys_clock_gettime() system call

I have been using clock_gettime functions with CLOCK_MONOTONIC_COARSE as the first parameter in my code like so:

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

However, when I run gperftools cpu profiler on my code, I get a relatively high percentage of calls to __sys_clock_gettime, at around 8.6%.

I checked my use of the CLOCK_MONOTONIC_COARSE with clock_getres() function, and it reveals a resolution of 4000000 ns, which is the right order of magnitude with 1 ms, I think.

Am I suppose to include another library in my code besides the time.h to let me use CLOCK_MONOTONIC_COARSE without making system calls? I would like to avoid this inefficiency.

Thanks!

Upvotes: 1

Views: 2092

Answers (2)

user941239
user941239

Reputation: 988

For those interested, here are the timings for all those clock_id.

Measure done on a corei7 gen7, kernel 4.4, 64bits.

With a scale of 100 for the fastest:

 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

So I am assuming, as of kernel 4.4, CLOCK_REALTIME, CLOCK_MONOTONIC and their COARSE variants all use vdso. This is confirmed by the fact that time -v shows a system time of zero, all the time is spent in userspace. The COARSE variant is only an optimization at the expense of precision.

The other clock_id are probably NOT using vdso and doing real system call. This is confirmed by the fact that the system time is a big portion of the total time.

Of course this might vary in subsequent kernels if more clock_id are implemented in the vdso.

Upvotes: 0

Mats Petersson
Mats Petersson

Reputation: 129524

Looks like it should still be a system call, if this patch is anything to go by: http://lwn.net/Articles/342018/

It just doesn't call specific functions to fetch the EXACT time from some hardware registers, which, at least on some hardware, is quite slow.

But there are lots of factors:

What hardware is it? clock_gettime() should be a virtual system call [vsyscall] on x86 and x86-64.

And finally, if you call it "as the first parameter" in a lot of function calls, then it's likely that it's simply how much time it takes.

I doubt there is any way to get current time without at least a virtual system call, since you do need some information from the kernel to get the current time - where is it supposed to find the current time from, if it doesn't make some sort of call to kernel code.

A virtual system call works by adding a little bit of "kernel code" into user-space, which has read-only access to certain pieces of the kernel memory-space, in particular "current process ID" and "parent process ID" and some types of time-information, such as "current time" and "CPU usage stats" I think. This allows the system call to be done completely in user-space, and thus is much faster than a "real" system call that transitions into kernel mode and back out again.

Upvotes: 1

Related Questions