From 5e94239967a4bb750b85c2ea977a2b2675a96c9f Mon Sep 17 00:00:00 2001 From: Misa Date: Mon, 13 Jul 2020 21:17:20 -0700 Subject: [PATCH] Optimize 30-mode FPS loop to use SDL_Delay() This patch optimizes the loop used to limit the framerate in 30-FPS-only mode so that it uses SDL_Delay() instead of an accumulator. This means that the game will take up less CPU power in 30-FPS-only mode. This also means that the game loop code has been simplified, so there's only two while-loops, and only two places where game.over30mode is checked, thus leading to easier-to-understand logic. Using an accumulator here would essentially mean busywaiting until the 34 millisecond timer was up. (The following is just what leo60228 told me.) Busywaiting is bad because it's inefficient. The operating system assumes that if you're busywaiting, you're performing a complex calculation and handles your process accordingly. And this is why sleeping was invented, so you could busywait without taking up unnecessary CPU time. --- desktop_version/src/main.cpp | 39 +++++++++++------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/desktop_version/src/main.cpp b/desktop_version/src/main.cpp index 1651d18e..7017e11f 100644 --- a/desktop_version/src/main.cpp +++ b/desktop_version/src/main.cpp @@ -62,9 +62,7 @@ volatile Uint32 timePrev = 0; volatile Uint32 accumulator = 0; volatile Uint32 f_time = 0; volatile Uint32 f_timePrev = 0; -volatile Uint32 f_accumulator = 0; -void inline gameloop(); void inline deltaloop(); void inline fixedloop(); @@ -369,15 +367,22 @@ int main(int argc, char *argv[]) while(!key.quitProgram) { - f_timePrev = f_time; f_time = SDL_GetTicks(); - const float f_rawdeltatime = static_cast(f_time - f_timePrev); - if (!game.over30mode) + + const Uint32 f_timetaken = f_time - f_timePrev; + if (!game.over30mode && f_timetaken < 34) { - f_accumulator += f_rawdeltatime; + const volatile Uint32 f_delay = 34 - f_timetaken; + SDL_Delay(f_delay); + f_time = SDL_GetTicks(); } - gameloop(); + f_timePrev = f_time; + + timePrev = time_; + time_ = SDL_GetTicks(); + + deltaloop(); } game.savestats(); @@ -388,26 +393,6 @@ int main(int argc, char *argv[]) return 0; } -void inline gameloop() -{ - while ((game.over30mode || f_accumulator >= 34) && !key.quitProgram) - { - if (game.over30mode) - { - f_accumulator = 0; - } - else - { - f_accumulator = fmodf(f_accumulator, 34); - } - - timePrev = time_; - time_ = SDL_GetTicks(); - - deltaloop(); - } -} - void inline deltaloop() { //timestep limit to 30