AShelly
AShelly

Reputation: 35580

Do CLOCK_MONOTONIC and CLOCK_MONOTONIC_COARSE have the same base?

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

Answers (3)

paulsm4
paulsm4

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.

Addendum

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

user941239
user941239

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!

  • Define first what is the accuracy you need for your timings. Is second enough, do you need milli second, micro, etc...
  • Have in mind, unless you are tinkering with RT systems, that time is a relative value! Imagine you called clock_gettime, and immediately after returning your thread gets interrupted for any kernel business: what is the accuracy you get? That is exactly the famous question that defeated HAL in 2001: A space Odyssey: "what time is it?".
  • From that you can derive what is the type of clock you need.
  • You can mix MONOTONIC and the COARSE version of it and still compute delays or compare (that was the original question). But of course the precision is that of the less precise.
  • The monotonics are best suited to do time delays and do comparisons since they don't depend on the real time (as your watch displays). They don't change when the user changes the actual time.
  • On the contrary, if you need to display at what time (meaningful for the user) an event occurred, don't use monotonic!

Upvotes: 5

Seth Robertson
Seth Robertson

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

Related Questions