[ C++11 – Part 2 ] Timing

std::chrono


Today, we’ll learn how to use the chrono library. It’s used for timing functionality. It supports a variety of different operations and can be quite daunting in the beginning. The library contains several new types, but I’ll try to explain all of them shortly. But first a few practical tips that will make using std::chrono easier.

using std::chrono


For working with chrono I suggest writing using namespace std::chrono somewhere your code ( preferably at the top ). This means you don’t have to write std::chron:: in front of everything.

Is easier to read than :

Usually, using namespace statements are discouraged to avoid name collisions, but since we are writing std::chrono we could only get name collisions with items in the std::chrono library, which is less likely to happens.

Includes


To make sure everything compiles as it should, please add the headers and using to the top of your file :

About this part


I also want to point out that this guide is rather comprehensive. This is because it’s a good idea to have deep understanding how the various components of the chrono library works. Just writing this guide helped me to understand a lot of it. My hope is that it will help you too.

If you want more information, you can look at the en.cppreference documentation for chrono. This resource covers most, if not all of the features in C++11 with detailed information and good examples. It’s very useful for learning and as a reference.

Overview


Here is a quick overview of the chrono library.

I will now go over each of these components, starting with the basic one, ratio

ratio


The ratio is actually not a direct part of chrono but it’s very useful for working with chrono and just useful in general. A ratio is just that, a ratio or a fraction if you will. For example the ratio between a minute and a second is 60 / 1 since you need 60 seconds to make a minute. ration is defined in it’s own header file, simply called ratio

Definition


The class is templated. The definition looks like the following :

Even though this is a templated class, which can be complicated and hard to understand, the template arguments are quite straight forwards.

Template arguments :

  • Num  – the numerator, or simply the top part of a fraction
  • Denom  -is the denomerator or bottom part of fraction

These two numbers forms a fractions :

Num / Denom

Usually these numbers are dividable by 10, so you end up with numbers like 1000 or 0.001

Both variables are of the type std::intmax_t, which means they are the biggest possible type of signed int available, usually at least 64 bits. For example int64_t.

Predefined ratios


In the chrono library ticks are stored in fractions of second. A few examples :

  • A second : ratio < 1 /1 >
    • A second is 1 / 1 of a second.
    • Can also be written as std::ratio< 1 > since the denomerator defaults to 1
  • A millisecond : ratio < 1 /1000 >
    • A millisecond is 1 / 1000 of a second
  • A minute : ratio< 60 /1 >
    • A minute is 60 / 1 seconds.
    • Can also be written as ratio< 60 > since the denomerator defaults to 1

Resource on ratios


As a part of the ratio header, there’s a lot of predefined ratios ( milli, nano, kilo, mega, … ). Because ratio is not directly a part of the chrono library ( it has other uses than just chrono ), there is no predefined values for minutes, hours, etc. There’s just the ones based on the standard units that’s used for distance or weight. You can refer to either of these using the std:: prefix. Since the ratios are not part of the chrono library, it’s just std:: and not std::chrono::.

For a full list of the predefined values, take a look at the documentation.

duration


duration( or std::chrono::duration ) is one of the basic classes of the chrono library. As the name suggests, it stores a time duration. Or a distance between to points in time if you like.

Member variables


It’s quite simple in its structure, it only has two member variables :

  • rep
    • an arithmetic type ( basically any unit that can hold a number ) that stores the number of ticks ( number of seconds, minutes, years, etc.. ).
  • period
    • a ration containing the type of unit rep stores. In effects this means “how many seconds/minutes/years,… is one tick.”

Constructing a duration


The creation of a duration is a bit complex as it involves two template arguments that sets representation type and a ratio plus the constructor.

teamplate arguments


The actual templated part looks like this :

Template parameters :

  • rep – the type to hold the ticks
    • Typically int or double
  • ratio – the type units used by duration
    • Covered above

The ratio defaults to 1 / 1, meaning seconds. The number of ticks the duration should use are sent to the constructor in the ordinary way using the parenthesis after the variable name.

To create a duration for containing seconds, you can do :

This creates a duration for holding seconds.

Other ratios


To create different durations we can use the ratio like above.  For example 10 millisecond becomes :

We can simplify this by using the predefined ratios already in C++11 :

Okay, but what about 10 minutes? This is quite similar to the above :

We do std::ratio< 60, 1 > because a minute is 60 / 1 seconds which or simply 60 seconds. But we can’t simply this like above because there is not predefined ratio for minutes. The predefined ratios are all “clean” ratios like 1 / 100, 1000 / 1, 1 / 10, 10 / 1, etc…

Predefined durations


But there is another, even simpler way! Just like in ratio there are predefined values in duration And they’re very simple to use.

So say you wanted a duration of 10 milliseconds :

Or 10 minues :

Constructor


The duration has three major constructors

  • Default, empty constructor
    • Looks something like this : duration( )
    • Initializes the duration
  • Constructor with rep variable
    • Looks something like this : duration( rep ) where red can be int, doube or similar
    • Sets the internal tick variable to the variable passed in constructor
    • This is the one we’ve used up until now
  • Construct for other duration
    • Looks something like this : duration( duration )
    • Sets the internal tick variable based on the passed duration
    • The = operator works in the same way
From rep type

Takes a value ( rep ) as argument and sets the ticks of the duration to it.

From other duration type

Takes a duration as argument and sets the ticks of the duration to it. Will convert between the two types of duration based on the ration. This means that if you pass a minutes duration to a seconds duration, you will get the number of minutes * 60 ( because there are 60 seconds in a minute.

Example

This creates a 10 second duration

Duration functions


Duration has a few functions, but I’ll just cover two of them now

  • count
    • Returns the number of ticks
  • duration_cast 
    • Converts a duration of duration into another.

count


This function simply returns the number of ticks. So for our 10 millisecond example, this will be 10.

Code example :

Output :

duration_cast


When we’re working with two different types of durations things can get a bit weird. A simple example : what’s 3 minutes minus 36 seconds. The answer is quite simple for a human to figure out. But the results in your program needs to be a duration but which unit? Since 3:24 can’t be expressed exactly in minutes, we need to change either the 3 minutes to seconds, or the 36 seconds to minutes. Here’s where duration_cast<> comes in.

This simply casts our 3 minutes into 180 seconds. After doing that, we can simply do :

And we’ll get the result in seconds ( 144. ) If you had converted this to minutes, it would take the whole minutes and strip the seconds. Meaning you would end up with 2

Floating points


Up until now, we’ve only used integer values for representing ticks. This means we can only represent whole tick. So a duration of seconds using an int to represent ticks means it can only represent whole seconds. Consider the following code :

This will fail ( won’t compile ) because you loose precision. You could use a duration_cast to fix this, but you’ll loose the precision and end up with 0duration_cast is way of telling the compiler “yeah, I know this will loose precision, just do it!”

So instead we can create a duration of seconds represented as a double :

Output :

Count : 0.016

This is not the same as the predefined duration seconds because all the predefined durations uses int.

Unlike the previous example, this won’t fail because you don’t loose precision. In fact, you could change the ratio to store years :

This will convert the 16 ms to years. If you did yearsAsDouble.count()
you would get roughly 5.07356672 × 10^-9 ( 0.00000000507356672 ) years.

Clocks


Clocks are just objects that is used for finding the current time. They are static, which means that there will only be one of each clock type. There is also just one member function ( also static member function, now() . The function now() returns the current time as time_point. I will cover time_points later.

Clock also have a tick rate which state how accurate they are. For instance : a clock has a tick rate of seconds, it can’t be used to measure milliseconds. The tick rates are represented as ratios.

Clock types


There are three available clocks in the chrono library.

  • system_clock
    • Full name : std::chrono::system_clock
    • The wall clock, use this if you just want to know the current time and date
    • This clock may be adjusted by either daylight saving time ( DST ) or leap seconds.
    • Can be mapped to C-style points and can therefore be easily printed.
  •  steady_clock
    • Full name : std::chrono::steady_clock
    • This clock is monotonic, this means will never be adjusted, so it’ll never be affected by things like DST and leap seconds
    • Best suited for measuring intervals
  •  high_resolution_clock
    • Full name : std::chrono::high_resolution_clock
    • Shortest tick available ( will be updated most often )
    • Might be alias of std::chrono::system_clock or std::chrono::steady_clock, or a third, independent clock.
      • This means it’s not guaranteed to be monotonic like steady_clock
    • Use this for benchmarking

That’s really all you need to know about clocks, but in the next part we’ll be exploring them more.

time_point


time_point<( or std::chrono::time_point) is the central class of the chrono library. I’ll spare the implementation details for now and just say that it contains various information about the current point it in time.

Construction


The constructor for a time point looks something like this :

As you can see, its a templated class that takes both a clock, and a duration. The duration is the duration the time_point uses. This defaults to the duration of the clock ( as you can see from the typename Clock::duration part. )

Simplified constructor


Luckily though don’t have to specify either of the arguments. So a really simple way to construct a time_point is :

You can use stady_clock or system_clock instead of high_resolution_clock.

This is equal to writing :

A bit more complex, but it means the exact same time : a time_point that uses a high_resolution_clock and has the same duration as the high_resolution_clock. I see no reason to use this method as opposed to the simpler one, but I want to explain the template arguments as well as I can.

Using custom ratio


But what if we wanted to specify our own duration? Well then we have to set the second template argument as well. Say we wanted to specify milliseconds as our duration time unit. Remember that duration has predefined constants for this.

This means we can simply do :

Full constructor


Now let’s do something even worse. Say we wanted a time_point that uses half minutes ( 30 seconds ) as the time units. I have no idea why anyone would want this, but it’s just a ( somewhat contrived ) example. As with some other examples, I do not encourage writing code like this. It’s horribly hard to read and very hard to understand unless you know the different part of the chrono libraries. Okay, here we go :

Yup, that’s a template argument, inside a template argument, inside a template argument! Don’t write code like this! If you need a specific time ratio, at least put the ratio and duration in separate objects ( I’ve shown you how to use the constructors above. ) Also make sure they’re well named like ratio30sec and duration30sec. That should give the reader at least a small hope at knowing what’s going on.

I added this example because if you understand this constructor and how it works, you understand the major parts of std::chrono

Initialization


As stated above, the static member function of clocks, now() returns a time_point of the current point in time.

That means we can just use auto to create a time_point too!

Simple as that, we’ve created a time point. The type of this object will be exactly the same as

Only it’s even simpler, and we’ve initialized it to the current point in time at the same time!

Difference between two time_points


And finally we can do some actual timing! Time points supports arithmetic operations. This means you can say time_point_x - time_point_y. This will result in a duration But what is the kind of duration. Seconds? Milliseconds? Years? Actually there is no one answer, it’s implementation defined. But the result is almost certain to be less than one second.

Since we can’t know what the resulting value is, we have two options. Say we have the following code :

And wanted to know the result of t1 - t2 Our two options are :

  1. Use auto
      • Nice and simple
      • But we can’t control the type of result.
  2. Use duration_cast
      • Takes the result of t2 - t1 and casts it into a duration of milliseconds and uses it to set result
      • This is a bit harder, but now we have full control over the type of duration.
      • If you want higher precision, you can use microseconds or nanoseconds
      • If you want higher precision, you can use microseconds or nanoseconds

Delta timer


So now let’s use all this knowledge and make a delta timer. A delta timer is used in games to tell the difference between two frames. The code is relatively simple and will show one ( of many ) ways to use the chrono library.

Notes


  1. Get the current time
    • We need this to calculate the difference in the next step
  2. Take the dif and store it in a duration
    • Stored in seconds ( since it’s the default )
    • Represented as double
  3. Reset time_prev
    • We need this point because we always need to know the time_point of the previous frame
  4. Return the results
    • Finally we return the time since last frame as fractions of a second
    • Can be a very small value like 0.000000001 ( 1ns )

A note about time units


This section just describes my reasoning for using seconds stored as double. It’s very focused around game programming and not crucial to understanding chrono.

I choose to use seconds as double here because double allows higher accuracy than int. And even though the game will almost certainly use less than 1 second on one frame, using seconds over milliseconds as time units means that the number will always be on the form 0.x. It also ensure that the delta won’t be exactly 0.

If the delta is 0 on one frame, no movement would happen ( I will get into this in the next SDL2 part ). If it only happens in one frame, the effect might not be that bad. But if it happens 100 frames in a row, that would be 100 frames without movements. And that would be bad!

So, in my opinion, it’s better to always have a delta of 0.x as it ensure that there will always be at least a tiny fraction of movement. The fact that the delta is a small number can be countered by multiplying with a great number in the function that calculates movement ( we’ll see this in the next SDL2 part too! )

Conclusion


The chrono library is very useful and makes it easy to deal with timing. It enables high precision timing, and makes it easy to find difference between two points in time. There are also other libraries that uses chrono like the threading library. I might write about the threading library later. There is also a post about timing in games coming up soon ( as mentioned in the above post. )


Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

You can also email me : olevegard@headerphile.com
Share

2 thoughts on “[ C++11 – Part 2 ] Timing”

  1. I know I’m a little late to the game here, but… seconds for game timing? You’re kidding right? A frame should take ~16ms! If you want 60fps anyway. Even 30fps is ~32ms. But for games I want microseconds, just like every engine I’ve ever used (UE4, CryEngine, and all the id Software code I’ve seen).

    Just a heads up for anyone that comes along. Higher resolution let’s you know if you can run another physics or AI pass before rendering another scene to get finer grain physics (it’s really awesome if you can do two physic updates per frame, but difficult once a game gets serious).

    1. Hello there 🙂

      I think you are misunderstanding me. I use fractions of seconds ( aka milliseconds, microseconds, nanoseconds, etc… ) just represented as seconds. This which allows for very high precision. If we represent time as fractions of seconds we get values like 0.016 for 16 ms.

      The reason why I mention seconds a lot is because it’s easier to relate to. But please tell me which part of the post says to use seconds for game timing so I can change it and improve my post.

Leave a Reply

Your email address will not be published. Required fields are marked *