High-Resolution Timers

SDL Performance Counter vs Ticks

How does using SDL_GetPerformanceCounter() differ from using SDL_GetTicks64()?

Abstract art representing computer programming

SDL_GetPerformanceCounter() and SDL_GetTicks64() are both functions provided by SDL for timing purposes, but they serve different needs and have distinct characteristics:

Resolution

The main difference lies in their resolution. SDL_GetPerformanceCounter() offers a higher resolution timer, often at the nanosecond level, while SDL_GetTicks64() provides millisecond precision.

#include <SDL.h>
#include <iostream>

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_TIMER);

  Uint64 perfCounterStart{
    SDL_GetPerformanceCounter()};
  Uint64 ticksStart{SDL_GetTicks64()};

  // Simulate some work
  for (int i{0}; i < 1000; ++i) {
    std::cout << "Working...\n";
  }

  Uint64 perfCounterEnd{
    SDL_GetPerformanceCounter()};
  Uint64 ticksEnd{SDL_GetTicks64()};

  std::cout << "Performance Counter delta: "
    << perfCounterEnd - perfCounterStart
    << "\nTicks delta: "
    << ticksEnd - ticksStart << '\n';

  SDL_Quit();
  return 0;
}
...
Working...
Working...
Working...
Performance Counter delta: 413164
Ticks delta: 41

In this example, you can see that the performance counter captures a much more precise time difference.

Units and Conversion

SDL_GetTicks64() always returns milliseconds, making it straightforward to use. However, SDL_GetPerformanceCounter() returns platform-specific units, requiring conversion using SDL_GetPerformanceFrequency() to get meaningful time intervals:

#include <SDL.h>
#include <iostream>

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_TIMER);

  Uint64 perfCounterStart{
    SDL_GetPerformanceCounter()};
  // Simulate some work
  for (int i{0}; i < 1000; ++i) {
    std::cout << "Working...\n";
  }
  Uint64 perfCounterEnd{
    SDL_GetPerformanceCounter()};

  double secondsElapsed{
    static_cast<double>(perfCounterEnd -
      perfCounterStart) /
    SDL_GetPerformanceFrequency()};

  std::cout << "Seconds elapsed: " <<
    secondsElapsed << '\n';

  SDL_Quit();
  return 0;
}
...
Working...
Working...
Working...
Seconds elapsed: 0.0456831

Use Cases

SDL_GetTicks64() is suitable for general timing needs, like measuring longer intervals or implementing game logic that doesn't require extreme precision. SDL_GetPerformanceCounter() is ideal for high-precision timing, such as frame time calculations, performance profiling, or implementing smooth animations.

In game development, you might use SDL_GetPerformanceCounter() for your main game loop timing, while SDL_GetTicks64() could be used for less critical timings like cooldowns or periodic events.

This Question is from the Lesson:

High-Resolution Timers

Learn to measure time intervals with high accuracy in your games

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

High-Resolution Timers

Learn to measure time intervals with high accuracy in your games

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 53 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved