Understanding Application Loop Speed and CPU Usage in SDL2
How fast does the while(true)
loop run? Can it use 100% CPU?
By default, a simple while(true)
loop (or while(shouldContinue)
where shouldContinue
remains true) in C++ will run as fast as the CPU possibly can. Yes, this can lead to 100% usage of a CPU core.
Busy-Waiting
This behaviour is often called busy-waiting. The CPU isn't waiting for an external event or pausing; it's actively executing the loop's instructions over and over again at maximum speed.
#include <SDL.h>
#include "Window.h"
int main(int argc, char** argv) {
SDL_Init(SDL_INIT_VIDEO);
Window GameWindow;
bool shouldContinue{true};
SDL_Event Event;
// This loop runs as fast as possible
while (shouldContinue) {
while (SDL_PollEvent(&Event)) {
if (Event.type == SDL_QUIT) {
shouldContinue = false;
}
}
// Hypothetical Update logic
// UpdateGameObjects();
// Hypothetical Render logic
// RenderScene();
// NO DELAY HERE! <--- This is the key issue
}
SDL_Quit();
return 0;
}
Why 100% CPU Usage is Bad
While making the loop run fast might seem good for responsiveness, consuming 100% CPU is generally undesirable for several reasons:
- Power Consumption: Maxing out the CPU uses significantly more electricity, which is particularly bad for battery life on laptops or mobile devices.
- Heat Generation: High CPU usage generates more heat, potentially leading to thermal throttling (where the CPU slows itself down to prevent overheating) and increased fan noise.
- Starving Other Processes: Your application might prevent other background processes or even the operating system itself from getting sufficient CPU time, potentially making the entire system feel sluggish.
- Unnecessary Work: In many cases, especially in games, you want to target a specific frame rate (e.g., 60 frames per second). Running the loop thousands of times per second only to draw the same thing repeatedly is wasteful.
Controlling Loop Speed
To prevent this, you need to introduce ways to regulate the speed of your application loop. Common techniques include:
- Frame Limiting with Delays: Calculate how long each iteration (frame) took. If it was faster than your target frame time (e.g., 16.67 milliseconds for 60 FPS), use a function like
SDL_Delay()
to pause the application for the remaining time. - Vertical Sync (VSync): When creating your SDL Renderer, you can request VSync. This instructs SDL to synchronize your application's rendering (
SDL_RenderPresent()
) with the monitor's refresh rate. This effectively caps your frame rate to the monitor's rate (commonly 60Hz, 120Hz, 144Hz, etc.) and often allows the CPU/GPU to idle when waiting for the next refresh, reducing usage.
We will cover these techniques in detail in later lessons on rendering and timing. For now, be aware that an uncontrolled loop runs at maximum speed and that strategies exist to manage this effectively.
Implementing an Application Loop
Step-by-step guide on creating the SDL2 application and event loops for interactive games