Clocks And Timing

Overview

Timing and delay functions, by their very nature, a somewhat platform specific. The C and C++ languages do make some attempt to standardize these, in where they provide a standardized front-end function that then goes and calls system-specific functions.

C++11

C++11 allows the use of the standard library to create delays in the current thread. These functions seem to have been copied across from the Boost libraries.

 

 

Clocks

C++11 introduced three types of clocks:

  • system_clock. Driven from the system-wide realtime clock. It is the only C++ clock which can map its time points to C-style time, and then be displayed.
  • steady_clock. A monotonic (never decreasing) clock that is never adjusted.
  • high_resolution_clock. A clock with the shortest tick period available.

Each clock has a starting point (epoch) and tick rate. For example, a clock may have an epoch of 1 Jan, 1970 (UNIX epoch) and tick once per second.

Note that all three are somewhat implementation/system specific (rely on OS calls).

The object returned from any clock::now() is a time_point.

Printing out the value of a time_point:

system_clock has the unique ability to convert to a time_t object (and be printed as a readable time).

Run the above example online at https://wandbox.org/permlink/UrLQ05x1Ds7FwVeR.

The subtraction of two time points intuitively returns a duration object.

Run the above example online at https://wandbox.org/permlink/EnPb9aag3TCkx3Lu.

Durations

The std::chrono::duration class can be used to represent a duration of time. It also has the benefit of being able to represent a duration in many different units (e.g. seconds, milliseconds, microseconds).

Run the above example online at https://wandbox.org/permlink/KSpr5KgvSIDimNb5.

Note: To use std::chrono::duration without having to specify the units requires C++17, as template argument deduction feature is required. If you are using C++11 or C++14, you would have to change the above to:

Run the above example online at https://wandbox.org/permlink/bprXREr562iFH6dM.

To print a std::chrono::duration, you must first convert it to a specific unit-specifying overload, and then call the count() method to return the integer number of counts in this unit. This can then be easily converted into a string, or spat directly to std::cout.

Run the above example online at https://wandbox.org/permlink/9u6as1nfcpWv1cBe.

You can also use a duration<float> object to move away from integral numbers of ticks and have higher precision (note that you are still limited by the precision of the clock). This next example shows how to use  duration<float> with the subtraction of two time points.

Run the above example online at https://wandbox.org/permlink/EnPb9aag3TCkx3Lu.

“DateTime” Objects

Although C++11/C++14 provides a good amount of time related functionality, I still feel that a solid DateTime object is missing from the standard library. A good DateTime object should represent absolute instance in time, and should allow for subtraction of two DateTime objects (to produce a duration object), comparison of DateTime objects (based on which is in the future compared to the other) and the addition of a Duration object to a DateTime object to produce a new DateTime object.

The best DateTime object I have found is part of the SGP4 library. You can download the entire repository from https://github.com/dnwrnr/sgp4, or just download the DateTime.h file below:

Time-Related Libraries

File Name Availiable For Contains Description
<chrono>      
<time.h>/<ctime>   nanosleep()
clock_t
time_t
 
<unistd.h>   sleep()
usleep()
 

Sleeping

C++ provides many ways of sleeping a thread (i.e. creating a delay which does not use up valuable processor time).

Note that many of these functions will not be defined for embedded systems.

this_thread::sleep_for() (the preferred way)

sleep_for(std::chrono::duration sleep_duration) blocks the current thread by at least the specified sleep duration.

Run the above example online at https://wandbox.org/permlink/hrJqJseiLbJQcHxI.

unistd.h

unistd.h provides POSIX-compliant delay functions, which work in both C and C++ code. It is available natively on Linux and MacOS, but not Windows. It is available in Windows via Unix-compatibility layers such as CygWin and MinGW.

usleep() is deprecated, and not present in the latest version of the POSIX standard.

Some examples…

time.h

time.h provides POSIX-compliant delay functions, which work in both C and C++ code. It is available natively on Linux and MacOS, but not Windows. It is available in Windows via Unix-compatibility layers such as CygWin and MinGW.

Note that when using nanosleep(), your resolution will likely be far smaller than the minimum time-step that the system supports, and your delay will be rounded

Some examples…

Windows.h

The Windows API provides the Sleep() function. This method only works if you are compiling on Windows.

Boost

The Boost library has delay functionalies.

 

Posted: May 7th, 2014 at 4:17 pm
Last Updated on: March 8th, 2018 at 11:43 am

Leave a Reply