C Tutorial: Use Linux's high resolution clock
Clock_gettime
The clock_gettime system call is a successor to the gettimeofday system
call with a few key changes: higher precision and the ability to request specific clocks.
It fills in a structure containing two fields: a seconds and a nanosecond count of the time
since the Epoch (00:00 1 January, 1970 UTC). This is similar to the struct timeval
that
gettimeofday used except that the microsecond field is now replaced with a nanosecond field.
The clock_gettime system call has the following usage:
The second parameter is the time structure that will be filled in by the system call to contain the value of the clock. The first parameter, clock ID, allows you to specify the clock you are interested in using. The following are available:
clock ID | meaning |
---|---|
CLOCK_REALTIME | System-wide real-time clock. This clock is supported by all implementations and returns the number of seconds and nanoseconds since the Epoch. This clock can be set via clock_settime but doing so requires appropriate privileges. When the system time is changed, timers that measure relative intervals are not affected but timers for absolute point in times are. |
CLOCK_REALTIME_COARSE (Linux-specific) | Faster than CLOCK_REALTIME but not as accurate. |
CLOCK_MONOTONIC | Represents monotonic time since some unspecified starting point. This clock cannot be set. |
CLOCK_MONOTONIC_RAW (Linux-specific) | Similar to CLOCK_MONOTONIC, but provides access to a raw hardware-based time that is not subject to NTP adjustments. |
CLOCK_MONOTONIC_COARSE (Linux-specific) | Like CLOCK_MONOTONIC but faster and not as accurate. |
CLOCK_PROCESS_CPUTIME_ID | High-resolution per-process timer from the CPU. |
CLOCK_THREAD_CPUTIME_ID | Thread-specific CPU-time clock. |
As with gettimeofday, the resolution depends on the implementation, so do not always expect to get nanosecond precision. The clock_getres system call returns the resolution of the specified clock. This is informational data since you do not need to apply any scaling factors to data returned by clock_gettime: the values are in seconds and nanoseconds.
For example, if a clock's resolution is 1024 Hz (1/1,024 second), then the resulting resolution is 976562.5 nanoseconds, which will be reported by clock_getres as 976562.
Which clock to use
For getting the system's idea of the time of day (in seconds since the Epoch), one should use
clock_gettime(CLOCK_REALTIME, &tp)
.
For measuring elapsed time, CLOCK_MONOTONIC is recommended. This clock will not necessarily reflect the time of day but, unlike CLOCK_REALTIME, it is guaranteed to always be linearly increasing (although not necessarily between reboots). CLOCK_MONOTONIC is affected by adjustments caused by the Network Time Protocol (NTP) daemon. However, NTP adjustments will not cause this clock to jump; it's rate might be adjusted to compensate for clock drift. CLOCK_REALTIME, on the other hand, may leap forward or even backward after a time adjustment.
CLOCK_MONOTONIC_RAW is available only on some Linux kernels and the tick rate will never be adjusted by NTP. This is fine for short programs but a clock drift over longer periods of time may produce inaccurate results.
The CLOCK_PROCESS_CPU_TIME_ID clock measures only the CPU time consumed by the process. If the kernel puts the process to sleep, the time it spends waiting is not counted. If a process has multiple threads, CLOCK_THREAD_CPUTIME_ID is similar but measures only the CPU time spent on the thread that is making the request.
Example
To compile a program that uses clock_gettime, you need to link with librt.a
(the real-time
library) by specifying -lrt
on your compile line.
This example marks the start time by getting the value of CLOCK_MONOTONIC. The process then sleeps for a second and marks the stop time by getting the value of CLOCK_MONOTONIC a second time. It then does the same thing again but uses CLOCK_PROCESS_CPUTIME_ID. Since the CPU is not used for the time that the process is sleeping, the results are substantially shorter.
Save this file by control-clicking or right clicking the download link and then saving it as gettime.c.
Compile this program via:
If you don't have gcc, You may need to substitute the gcc command with cc or another name of your compiler.
Run the program: