My first foray into performance optimization came when attempting to write computer games for the Intel 80×86 family. The clunky graphics of CGA, MCGA, gave way to the higher resolutions but fewer colours of EGA, and VGA. For PC computer games though at that golden point in time, it was all about 320x200x8bpp and more specifically the infamous ModeX.
This post isn’t about ModeX, or any of the other modes really, it’s about how the drive to produce faster graphics to enable more realistic animation and game play led to a lifelong obsession with getting every last piece of performance out of a usually reluctant piece of hardware.
But enough history, needless to say the intent of these posts is to identify approaches and techniques or perhaps establish some principles that may help you the next time you are asked to go and optimize something. When I was spending all my time cranking through different assembly implementations of sprite drawing routines, looking for the magic combination of opcodes (CPU instructions) to yield the best possible performance, I was guilty of the cardinal sin of Performance Optimization – I optimized the code that I found most interesting rather than the code that most needed optimizing.
What I should have done is to determine which portion(s) of the game loop were actually being spent rendering sprites versus other activities such as maintaining object lists, handling input, updating state etc. Those results would have told me exactly where the time was being spent, and where I should focus the optimization.
Back in those dark ages there were not any of the tools that we now take for granted, and those that were available were very expensive. So the measurement code I used was not the best, but it did serve a purpose. Remember this was a time when delays were implemented with a loop of assembly code – which would result in very different behaviours when running on different systems.
All of this brings me to the point (finally) for this post, you must know exactly where time is being spent before considering doing any kind of performance work. To do this you need an accurate tool, and you have to use it frequently and you must understand the system factors that can influence its behaviour.
We might want to adapt the old carpenters adage of ‘Measure twice, cut once’ to the Optimizers adage of ‘Measure often, optimize with precision’