Reputation: 35580
The man page for clock_gettime()
describes CLOCK_MONOTONIC_COARSE as:
A faster but less precise version of CLOCK_MONOTONIC. Use when you need very fast, but not fine-grained timestamps.
What does it mean for one to be a "version of" the other?
Can I validly compare one to the other, assuming I truncate a CLOCK_MONOTONIC value to the same precision as the coarse one?
Upvotes: 4
Views: 6974
Reputation: 121759
Here is the man page that lists the different "versions" of Posix/Linux clocks:
https://linux.die.net/man/2/clock_gettime
Sufficiently recent versions of glibc and the Linux kernel support the following clocks:
CLOCK_REALTIME
System-wide clock that measures real (i.e., wall-clock) time. Setting this clock requires appropriate privileges. This clock is affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the clock), and by the incremental adjustments performed by adjtime(3) and NTP.
CLOCK_REALTIME_COARSE (since Linux 2.6.32; Linux-specific)
A faster but less precise version of CLOCK_REALTIME. Use when you need very fast, but not fine-grained timestamps.
CLOCK_MONOTONIC
Clock that cannot be set and represents monotonic time since some unspecified starting point. This clock is not affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP.
CLOCK_MONOTONIC_COARSE (since Linux 2.6.32; Linux-specific)
A faster but less precise version of CLOCK_MONOTONIC. Use when you need very fast, but not fine-grained timestamps.
CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific) Similar to CLOCK_MONOTONIC, but provides access to a raw hardware-based time that is not subject to NTP adjustments or the incremental adjustments performed by adjtime(3).
CLOCK_BOOTTIME (since Linux 2.6.39; Linux-specific) Identical to CLOCK_MONOTONIC, except it also includes any time that the system is suspended. This allows applications to get a suspend-aware monotonic clock without having to deal with the complications of CLOCK_REALTIME, which may have discontinuities if the time is changed using settimeofday(2).
CLOCK_PROCESS_CPUTIME_ID High-resolution per-process timer from the CPU.
CLOCK_THREAD_CPUTIME_ID Thread-specific CPU-time clock.
As you can see above, CLOCK_MONOTONIC_COARSE was introduced in Linux 2.6.32. Here is the rationale (and the specific source patch):
https://lwn.net/Articles/347811/
After talking with some application writers who want very fast, but not fine-grained timestamps, I decided to try to implement a new clock_ids to clock_gettime(): CLOCK_REALTIME_COARSE and CLOCK_MONOTONIC_COARSE which returns the time at the last tick. This is very fast as we don't have to access any hardware (which can be very painful if you're using something like the acpi_pm clocksource), and we can even use the vdso clock_gettime() method to avoid the syscall. The only trade off is you only get low-res tick grained time resolution.
This isn't a new idea, I know Ingo has a patch in the -rt tree that made the vsyscall gettimeofday() return coarse grained time when the vsyscall64 sysctrl was set to 2. However this affects all applications on a system.
With this method, applications can choose the proper speed/granularity trade-off for themselves.
What use cases might benefit from using CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE?
In Linux 2.6.32 time frame (2010-2011), "...application workloads (especially databases and financial service applications) perform extremely frequent gettimeofday or similar time function calls":
Redhat Enterprise: 2.6. gettimeofday speedup
Many application workloads (especially databases and financial service applications) perform extremely frequent gettimeofday or similar time function calls. Optimizing the efficiency of this calls can provide major benefits.
Upvotes: 3
Reputation: 988
The short answer is YES (at least for Linux!), you can compare them, compute delays, etc...
The precision would be that of the less precise, most probably COARSE one.
See this short program:
#include <time.h>
#include <stdio.h>
int main()
{
int ret;
struct timespec res;
ret = clock_getres(CLOCK_MONOTONIC, &res);
if (0 != ret)
return ret;
printf("CLOCK_MONOTONIC resolution is: %ld sec, %ld nsec\n", (long)res.tv_sec, (long)res.tv_nsec);
ret = clock_getres(CLOCK_MONOTONIC_COARSE, &res);
if (0 != ret)
return ret;
printf("CLOCK_MONOTONIC_COARSE resolution is: %ld sec, %ld nsec\n", (long)res.tv_sec, (long)res.tv_nsec);
return 0;
}
It returns (Ubuntu 20.04 - 64bits - kernel 5.4)
CLOCK_MONOTONIC resolution is: 0 sec, 1 nsec
CLOCK_MONOTONIC_COARSE resolution is: 0 sec, 4000000 nsec
So MONOTONIC has nanosecond precision, and COARSE has 4 milliseconds precision.
Unlike above comment, I would on the contrary recommend to use the COARSE version when the timings you need allow.
Calls to the clock are so frequent in user programs that they have a place in vDSO
When you use COARSE versions, you have exactly zero system call, and it is as fast as your machine can run a few instructions. Thanks to vDSO your program fully stays in "userland" during the call with COARSE. With other types of clocks, you will have some system calls, and potential access to hardware. So at least a switch to "kernel" and back to "userland".
This of course has zero importance if your program just needs a dozen of calls, but it can be a huge time saver if, on the contrary, the program relies heavily on the clock. That is why, vDSO is there in the first place: performance!
Upvotes: 5
Reputation: 31461
CLOCK_MONOTONIC_COARSE
uses the same timebase as CLOCK_MONOTONIC (but specifically does NOT as compared to CLOCK_MONOTONIC_RAW
). Specifically, they both use wall_to_monotonic
to convert a value derived from tk's xtime. RAW uses a completely different time source.
Remember, that CLOCK_MONOTONIC_COARSE
is only updated once per tick (so usually about 1 ms, but ask clock_getres()
to be sure). If that accuracy is good enough, then by all means subtract your clock values.
Upvotes: 3