175

Among the timing functions, time, clock getrusage, clock_gettime, gettimeofday and timespec_get, I want to understand clearly how they are implemented and what are their return values in order to know in which situation I have to use them.

First we need to classify functions returning wall-clock values compare to functions returning process or threads values. gettimeofday returns wall-clock value, clock_gettime returns wall-clock value or process or threads values depending on the Clock parameter passed to it. getrusage and clock return process values.

Then the second question regards the implementation of these functions and as a consequence, their accuracy. Which hardware or software mechanism does these functions use.

It seems that getrusage uses only the kernel tick (usually 1ms long) and as a consequence can't be more accurate than the ms. Is it right? Then the gettimeofday function seems to use the most accurate underlying hardware available. As a consequence its accuracy is usually the microsecond (can't be more because of the API) on recent hardware. What about clock, the man page speak about "approximation", what does it mean? What about clock_gettime, the API is in nanosecond, does it means that it's able to be so accurate if underlying hardware allows it? What about monotonicity?

Are there any other functions?

Patrizio Bertoni
  • 2,582
  • 31
  • 43
Manuel Selva
  • 18,554
  • 22
  • 89
  • 134

2 Answers2

224

The problem is that there are several different time functions available in C and C++, and some of them vary in behavior between implementations. There are also a lot of half-answers floating around. Compiling a list of clock functions together with their properties would answer the question properly. For starts let's ask what the relevant properties are that we're looking for. Looking at your post, I suggest:

  • What time is measured by the clock? (real, user, system, or, hopefully not, wall-clock?)
  • What is the precision of the clock? (s, ms, µs, or faster?)
  • After how much time does the clock wrap around? Or is there some mechanism to avoid this?
  • Is the clock monotonic, or will it change with changes in the system time (via NTP, time zone, daylight savings time, by the user, etc.)?
  • How do the above vary between implementations?
  • Is the specific function obsolete, non standard, etc.?

Before starting the list, I'd like to point out that wall-clock time is rarely the right time to use, whereas it changes with time zone changes, daylight savings time changes, or if the wall clock is synchronized by NTP. None of these things are good if you're using the time to schedule events or to benchmark performance. It's only really good for what the name says, a clock on the wall (or desktop).

Here's what I've found so far for clocks in Linux and OS X:

  • time() returns the wall-clock time from the OS, with precision in seconds.
  • clock() seems to return the sum of user and system time. It is present in C89 and later. At one time this was supposed to be the CPU time in cycles, but modern standards like POSIX require CLOCKS_PER_SEC to be 1000000, giving a maximum possible precision of 1 µs. The precision on my system is indeed 1 µs. This clock wraps around once it tops out (this typically happens after ~2^32 ticks, which is not very long for a 1 MHz clock). man clock says that since glibc 2.18 it is implemented with clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) in Linux.
  • clock_gettime(CLOCK_MONOTONIC, ...) provides nanosecond resolution, is monotonic. I believe the 'seconds' and 'nanoseconds' are stored separately, each in 32-bit counters. Thus, any wrap-around would occur after many dozen years of uptime. This looks like a very good clock, but unfortunately it isn't yet available on OS X. POSIX 7 describes CLOCK_MONOTONIC as an optional extension.
  • getrusage() turned out to be the best choice for my situation. It reports the user and system times separately and does not wrap around. The precision on my system is 1 µs, but I also tested it on a Linux system (Red Hat 4.1.2-48 with GCC 4.1.2) and there the precision was only 1 ms.
  • gettimeofday() returns the wall-clock time with (nominally) µs precision. On my system this clock does seem to have µs precision, but this is not guaranteed, because "the resolution of the system clock is hardware dependent". POSIX.1-2008 says that. "Applications should use the clock_gettime() function instead of the obsolescent gettimeofday() function", so you should stay away from it. Linux x86 and implements it as a system call.
  • mach_absolute_time() is an option for very high resolution (ns) timing on OS X. On my system, this does indeed give ns resolution. In principle this clock wraps around, however it is storing ns using a 64-bit unsigned integer, so the wrapping around shouldn't be an issue in practice. Portability is questionable.
  • I wrote a hybrid function based on this snippet that uses clock_gettime when compiled on Linux, or a Mach timer when compiled on OS X, in order to get ns precision on both Linux and OS X.

All of the above exist in both Linux and OS X except where otherwise specified. "My system" in the above is an Apple running OS X 10.8.3 with GCC 4.7.2 from MacPorts.

Finally, here is a list of references that I found helpful in addition to the links above:


Update: for OS X, clock_gettime has been implemented as of 10.12 (Sierra). Also, both POSIX and BSD based platforms (like OS X) share the rusage.ru_utime struct field.

Community
  • 1
  • 1
Douglas B. Staple
  • 10,510
  • 8
  • 31
  • 58
  • Mac OS X doesn't have `clock_gettime`, hence the use of [`gettimeofday()`](http://www.songho.ca/misc/timer/timer.html) being a little more versatile than `clock_gettime()` – bobobobo Apr 17 '13 at 04:30
  • @bobobobo I agree that OS X doesn't have clock_gettime(), however gettimeofday() unfortunately measures the wall-clock time. I updated my post to give this info. If ms precision is enough, then I recommend getrusage() as the best clock for use as a timer. – Douglas B. Staple Apr 17 '13 at 14:35
  • "Monotonic" is not implementably about anti-wrapping (since any clock will have to either wrap or error when its datatype's maximum value would be exceeded) but rather about not being subject to time corrections which would cause irregular advancement, and especially not being subject to *backwards* corrections which might severely break interval calculations. – Chris Stratton Jun 12 '13 at 16:46
  • @ChrisStratton OK, fixed. Note however that one could in principle define a clock with an arbitrary-precision data-type (dynamically allocated). However, I'm almost positive what you say is true for all the clocks listed above. Also, the issues you mention are more important than a 64-bit counter theoretically wrapping around. – Douglas B. Staple Jun 12 '13 at 18:30
  • 1
    You haven't mentioned [`times()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/times.html) (with an s), which has existed in POSIX since Issue 1. Concerning GNU/Linux: According to the clock(3) man page, `clock()` from glibc 2.17 and earlier was implemented on top of it, but for improved precision, it is now implemented on top of `clock_gettime(CLOCK_PROCESS_CPUTIME_ID,...)`, which is also specified in POSIX but is optional. – vinc17 Sep 11 '14 at 15:02
  • Thanks @vinc17. I will take a look at it soon, when I have some free times(). – Douglas B. Staple Sep 15 '14 at 13:07
  • If I may resurrect this thread, does anyone know offhand the performance differences between the options given up? In other words, if I wanted to get better performance at the cost of losing accuracy, how would I go about it? – starflyer Mar 23 '15 at 20:15
  • 2
    @starflyer The precision of the clock is partly limited by the amount of time it takes to poll the clock. This is because, if I call the clock and it takes 1 µs to return, then the time the clock reports will be "off" by 1 µs from the perspective of the caller. This means that a highly accurate clock must also be low-latency. So typically one will not have the trade-off you're talking about: the cheapest clocks will also be the most accurate. – Douglas B. Staple Mar 23 '15 at 23:53
  • @starflyer What I use to time routines is the RDTSC instruction. On newer architectures (at least since 2007) this counter runs at constant frequency. Often you want to measure the number of CPU clocks and to do this you must know the frequency of the counter and the CPU core – Jens Munk Jul 26 '15 at 12:53
  • I would like to throw in `clock_gettime(CLOCK_MONOTONIC_RAW, ...)`, which is a very good choice for measuring durations on Linux. It is important to note, that *monotonic* and *not affected by NTP* are [two different things](http://stackoverflow.com/a/14270415/620382). – Zulan May 07 '16 at 07:05
  • 3
    Also most clocks do not care about daylight saving time / time zones, even if they are considered to be *wall clocks*. Both `time` and `gettimeofday` return, at least nowadays, seconds since epoch (a.k.a. unix-timestamps). This is independent of time zones / DST. Leap seconds are another story... – Zulan May 07 '16 at 07:18
  • 2
    For Android users, using CLOCK_MONOTONIC may be problematic since the app may get suspended, along with the clock. For that, Android added the ANDROID_ALARM_ELAPSED_REALTIME timer that is accessible through ioctl. some information on these and other suspend related information can be found [here](http://lwn.net/Articles/429925/) – Itay Bianco Jul 11 '16 at 07:15
  • I wrote this article on the different kinds of clocks and Linux. I hope you like it: https://medium.com/@jalalmostafa/on-system-clocks-time-functions-and-the-new-system-monitoring-tool-precimon-fad920f38b2e – Jalal Mostafa Nov 26 '19 at 07:58
24

C11 timespec_get

Usage example at: https://stackoverflow.com/a/36095407/895245

The maximum possible precision returned is nanoseconds, but the actual precision is implementation defined and could be smaller.

It returns wall time, not CPU usage.

glibc 2.21 implements it under sysdeps/posix/timespec_get.c and it forwards directly to:

clock_gettime (CLOCK_REALTIME, ts) < 0)

clock_gettime and CLOCK_REALTIME are POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html, and man clock_gettime says that this measure may have discontinuities if you change some system time setting while your program runs.

C++11 chrono

Since we're at it, let's cover them as well: http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (C++ stdlib is inside GCC source):

  • high_resolution_clock is an alias for system_clock
  • system_clock forwards to the first of the following that is available:
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock forwards to the first of the following that is available:
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

Asked at: Difference between std::system_clock and std::steady_clock?

CLOCK_REALTIME vs CLOCK_MONOTONIC: Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • 1
    Great answer that demystifies the typical implementations. That's what people really need to know. – Beeeaaar Aug 24 '18 at 21:56