Back to Optimizing

It's been a while since I lost wrote, but I have a good excuse, I've been focusing on creating the Android version of my game. The good news is that everything is working now. It's running on both Android 2.3+ and a slightly improved version for Android 4.4+ (it shows in full-screen). What I'm working on now is optimizing it to get the performance I want. I've written articles about optimization in the past, so I'll keep this short and to the point of what I've done so far.

Measure, Measure, Measure

I've written about this in the past, but I've found that when you're trying to optimize something it is extremely important to measure often and enough. Also, optimizing for a focused measurement doesn't always result in improvements in the real environment.

To try to do a better job at measuring I've been using histograms of the speed of what I'm measuring to get a better picture than just an average speed. I'm also using the profiler functionality in Visual Studio, but I can only use that for the PC version of my game, not directly against the Android binary. Still this led to useful insight.

Two Optimizations

When I profiled my code I found two areas I thought I could improve relatively easily. The first was an unnecessary calculation when I manipulate (translate or rotate) quads. I was recalculating the center of the quads even though for these operations that wasn't necessary. This was pretty straight-forward to improve and resulted in a significant speedup. You can see this in the picture to the right: PC-L-SS is the original version, and PC-L-SS-Opt Mutable is this first optimization.

After the above I ran the profiler again and determined that a significant amount of time was being spent on calculating sine and cosine operations. I did some Google searching and found an interesting discussion that describes a faster way to calculate sine (the source of this information contains more details). So, I implemented this alternative sine calculation and measured again. This resulted in the PC-L-SS-FastSin numbers in the histogram.

The average FPS numbers for the above are: original = 1,114, first optimization = 1,380, and second optimization = 1,411. Note that this is just running my game logic code, but not actually rendering via OpenGL. I did this in order to focus as much as possible on the area I was optimizing.

But What About Android?

So, the above is interesting and all, but I'm trying to optimize Android, not my PC version. So, since I can't use the profiler, I can just run the same measurements. This resulted in the histogram to the right.

Clearly from this both the first optimization (Opt Mutable) and the second additional optimization (Opt Sine) are significantly faster than the original. To summarize this even more, the average FPS for each are: original = 37.29, first optimization = 42.95, second optimization = 43.45. In this case the numbers are both the game logic and the actual rendering. Because I'm trying to evaluate the true game performance, in my attempt to get to 60 FPS, I thought this was more useful.

Still More Work to Do

While I'm pretty happy with the results of this initial optimization, it's still not performing as well as I want. The Android measurements above were done on a Nexus 4, and I'd really like it to run at 60 FPS with some headroom for slower devices. My profiler investigations have given me some ideas for more optimizations, but I expect them to be more difficult than the above.

No comments:

Post a Comment