# Computing Elapsed Time in SDL 2

#### Posted by Sean Francis N. Ballais on June 13, 2020 10:50 PM

Elapsed time is one of the fundamental aspects of games. It determines the time between two snapshots (i.e. frames) of a game, used in the physics subsystems, and a whole lot more. Computing the elapsed time incorrectly may lead to inaccurate simulations and/or unsatisfying gaming experiences. SDL 2, a cross-platform library used to build games, provides functions to help us compute our elapsed time.

The basic mechanism from SDL 2 that can be used for computing elapsed time is SDL_GetTicks(). This function returns the amount of time that has lapsed since the SDL library has been initialized in milliseconds. Note that SDL_GetTicks() returns an unsigned 32-bit integer. With this function, we can get the elapsed time in seconds through:

uint32_t startTime = SDL_GetTicks();

// Do awesome stuff here, like figuring out if the girl at the bar you're in who
// glanced briefly at you and does a quick hair flip is into you. You actually
// really can't tell from this example since she could just be adjusting her
// hair, and looking at someone behind you.

uint32_t currTime = SDL_GetTicks();

double elapsedTime = (currTime - startTime) / 1000.0; // Convert to seconds.


I’m using seconds here since it’s the SI unit for time, and I find it easier to perform calculations with the unit (Thanks, PSHS-EVC, my high school, for drilling SI units into me!). This is should be enough for many cases, including computing for the elapsed time between frames. However, SDL_GetTicks() is not enough when you want higher precision times. Tasks like profiling will benefit from higher precision. For that, we have SDL_GetPerformanceFrequency() and SDL_GetPerformanceCounter().

Quick Aside: If you want to store a large amount of time, like the total running time of the game, do not use float. The precision of the float type decreases fast, especially compared to a double, as the value increases. Prefer using a double or an integer (if you want microsecond precision that would be viable for ~5,843.02 centuries, use a 64-bit unsigned integer) to store the time. This blog post by Bruce Dawson delves into the problem.

SDL_GetPerformanceCounter() and SDL_GetPerformanceFrequency() gets the current value and frequency of the high resolution counter, which is a register present on modern CPUs, at least the x86 ones. We can get high precision timings from those two functions. Both functions return a 64-bit unsigned integer. Getting the elapsed is actually just similar to using SDL_GetTicks():

// Code based from here:
//   https://gamedev.stackexchange.com/a/110831/93942
uint64_t startTime = SDL_GetPerformanceCounter();

// Do other awesome stuff, like converting between pixels in screen space and
// meters in physics world space. Here's an article to learn how to do that:
//   https://seanballais.github.io/blog/box2d-and-the-pixel-per-meter-ratio/

uint64_t currTime = SDL_GetPerformanceCounter();

double elapsedTime = static_cast<double>(
(currTime - startTime) / static_cast<double>(SDL_GetPerformanceFrequency())
);


This should give us a high-precision elapsed time in seconds. A variation of this is actually what I use in my game engine. I previously struggled understanding this, so I’ll explain how this works. Performing currTime - startTime will give us the number of ticks there are between the two calls to SDL_GetPerformanceCounter(), which gets the current number of ticks there are on call to the function. Now, we have to convert those number of ticks to seconds. SDL_GetPerformanceFrequency() provides the number of ticks per second (i.e. the frequency). We can use that function to convert currTime - startTime into seconds. To convert to seconds, we just simply divide currTime - startTime by SDL_GetPerformanceFrequency(). We have to cast the latter to a double to prevent integer clamping, since both operands are integers. And that’s it! Here’s a little SI conversion to show that that division operation actually converts the number of ticks to seconds, where $$t_{1}$$ represents currTime, $$t_{0}$$ represents startTime, and $$n$$ represents the number of ticks per second of the high resolution counter.:

\begin{align} \frac{(t_{1} - t_{0}) \text{ ticks}}{1} \cdot \frac{1 \text{ seconds}}{n \text{ ticks}} &= \frac{(t_{1} - t_{0}) \text{ }\cancel{\text{ticks}}}{1} \cdot \frac{1 \text{ seconds}}{n \text{ }\cancel{\text{ticks}}} \\ &= \frac{t_{1} - t_{0}}{1} \cdot \frac{1 \text{ seconds}}{n} \\ &= \frac{t_{1} - t_{0}}{n} \text{ seconds} \end{align}

We’ve just learned that SDL 2 provides functions to help us compute the elapsed time. Choosing which to use will depend on your use case. Actually, we can take this up a notch by creating a Timer class that will handle computing the elapsed time. But, that’s on you. At the very least, I hope this provides you with guidance with regards to computing the elapsed time.

# Credits

Header image used is owned by Ansgar Koreng, obtained from Wikipedia (image is obtainable via this link), and used under the CC BY-SA 4.0.