Yes, that is a now a double dwarf fortress reference. SDL !!Science!! is nearly as good as dwarf fortress !!Science!!, but lacks sufficient dwarficide (and magma).
Why 60 FPS?
Modern LCD monitors mostly run at 60Hz, which means the image on it refreshes 60 times a second. This means if you are rendering at more than 60 frames per second you are wasting processing time on frames the user will never see. This is why we limit our frames to sixty per second. Thus, in game development, generally a consistent 60 fps is our goal, and the lower bounds for acceptable framerate is 30 fps.
A second is 1000 milliseconds. This means our time boundaries for a single frame are between 16.66 ms and 33.33 ms. The midpoint of this is 45 fps which clocks in at 22.22 ms/frame. Notice that if we’re already sitting at a comfortable 45 fps, we only need to lose 5.56 ms of processing to gain 15 fps to 60, but if we are sitting at 30 fps we must cut 11.11 ms of processing to gain the same amount up to 45. This leads into…
Eking out a 0.1 ms gain on a function you call one hundred times a frame leads to saving a massive 10ms. Doing so on a function you call once is a waste of your time. If you’ve profiled and found all your bottlenecks and you are still sitting at 58 fps, then maybe fixing ten 0.1ms problems gets you those last couple frames and that might be worth doing. The problem being it takes time and effort to do so, which you could probably be better spending elsewhere. Part of the function I hope this series will provide is letting you know about easy fixes that can improve performance without you having to put in hours of potentially fruitless work.
There is of course a slight hitch with attempting to optimize in very small timescales. SDL only provides a timing mechanism that is only granular down to the ms. Obviously this makes determining if you’ve saved small amounts of time by doing something a different way impossible with just SDL. I’m personally using Boost’s chrono functionality for profiling purposes only. Boost is not for the faint of heart, as you have to build it yourself unless you’re using Visual Studio (with questionable instructions, customized to your compiler). I certainly don’t want to be trying to teach you SDL while using Boost on top (or I suppose technically underneath), as that will significantly increase the knowledge floor from just C++ and data structures basics.
Anyway, chrono claims to allow us down to nanosecond granularity(which is a frankly ridiculously small amount of time). A nanosecond is one billionth of a second, light travels ~0.3 meters in that time. 1000 nanoseconds is a microsecond, and 1000 microseconds brings us back up to milliseconds. Profiling our profiling functionality (2 tick checks and a file out) leads to two results: 310 ns or 0 ns. This means that we cant really trust the accuracy in the nanosecond range as the clock update falls somewhere between those values, which really isn’t too much of a loss. I’m perfectly happy with microsecond granularity.
First up, our counter display methods cost us ~830 microseconds once a second, doing a printf instead of replacing the window title shaves maybe ~100 microseconds off of that. I don’t have anything to compare this to, but that seems high. It also means we’re spiking 0.8 ms higher every second. Just out of curiosity, I wonder how much of that is the bitwise and-ing if statement on sdl.screen->flags. !!Science!! says under a microsecond, so nothing.
Secondly, our frame limiter and counter calculations costs us ~1 microsecond. This means the fixed cost of calling this is so small that it doesn’t even make a dent. Thinking about optimizing this would be a waste of time and brainpower.