Why, When, Where

Submitted by epreisz on Sun, 02/11/2007 - 07:22.

Why we Optimize

So if optimization is often overlooked, why do we need to optimize our code at all? When we optimize, we are increasing the amount of work we can do on our graphics cards and CPUs. Essentially, we are making sure that the money we’ve spent on our hardware is not going to waste. Why buy today’s hardware if we are going to make it behave like yesterdays technology.

By optimizing our CPU and GPU, we are able to add more polygons, more physics, more AI – more of the elements that sell video games.

Where do we Optimize

Usually, only one resource in a computer is slowing us down from our next gain in framerate. Although there are many resources on our machine, when optimizing a video game, there are only a couple that we will concentrate on. Most of my experience leads me to believe that the CPU is the biggest single bottleneck in video games. Within a CPU bound application there are several trouble spots. Most engines cause the graphics drivers to work too hard. Drivers execute on the CPU and communicate with the GPU. Your application code also runs on the CPU. Common trouble spots include collision, culling, physics, and AI. Your CPU may also run slowly because of either excessive memory look-ups or inefficient memory use. Another major section of CPU code that will slow down your game is the OS. The OS usually doesn’t pose a problem unless we are doing something drastically incorrect.

Of all the areas that can cause us CPU issues, one stands out a likely trouble spot. Your graphics drivers. Every time you change render state and call draw, you are creating overhead. The overhead is very little, but by calling draw too many times, the overhead adds up and your performance drops. We will spend a lot of time covering this topic later.

The next most common resource we must consider is the GPU. As engines evolve, the GPU is becoming a more likely bottleneck. This is especially true of games with lots of visual effects driven by complex shaders.

Lastly, the third most common resource that limits us is the bus between the CPU and GPU. In some machines this bus is the AGP bus. In other machines, the newer PCI express is the bus we use. A PCIe bus is rarely a bottleneck since it is many times faster than AGP. The AGP bus is usually only a bottleneck when we are sending excessive amounts of data to the graphics card. In most cases, we can eliminate sending data to the graphics card every frame.

When do we Optimize

The question of when do we optimize still perplexes me. The answer is usually driven by a project’s available funds. I’m not sure if there is the perfect answer for this question; however, there are some guidelines.

  • Don’t spend excessive amounts time optimizing code that you don’t know is slow.
  • When writing code, choose to write faster code if it will take you an extra 15% or less time to write it. Otherwise, write the slow code and test it to see if the code has become an optimization opportunity.
  • Don’t wait to optimize until the very end of your project. The information you collect during optimization should influence your design at your next refactoring cycle. You don’t want your next optimization job to be so large that you have to push it aside.
  • Don’t spend time optimizing rapid prototyping. Rapid prototyping is for gathering information, unless you are prototyping an optimization system, then you are probably wasting your time.
  • Don’t optimize hotspots smaller than 8%, it’s probably not worth the time.
  • Some of the words used above are subjective. Excessive, faster, large, are all terms that you can interpret differently based on your experience. This is where you as a professional must develop skills and a “gut feeling”. These interpretations are case by case, and no too cases will be exactly the same. Good luck.