I noticed several threads about garbage collection on forums.xna.com this week. Is it just me or is everyone suddenly starting to worry about performance as they approach the end of the DreamBuildPlay competition?
The crucial first step in any performance investigation, and something that many people forget, is to figure out whether you even have a problem at all.
Step 1: an early-out optimization
Is your game already fast enough? If you are running at a steady 60 frames per second, you can relax. I'm always amazed by how many people get in a panic about garbage collection even though their game is running just fine.
Step 2: measure, measure, measure!
So, your game is too slow.
Why? Is this because of garbage collection, or could the problem be somewhere else?
The XNA Framework Remote Performance Monitor for Xbox 360 (now there's a catchy name if ever I heard one!) makes it easy to find out.
There are two performance counters that are particularly interesting for understanding how long your GC is taking:
- Garbage Collections (GC)
- GC Latency Time (ms)
The first value tells you how often the garbage collector has run. The column on the left is the total since the program started, while to the right it shows the number of collections in the last second. The latency value tells you how long the last collection took to complete. Multiplying these two numbers together will tell you exactly what percentage of your CPU is being spent on garbage collection.
- Garbage collections in the last second = 40
- GC Latency Time = 2
- Total GC time = 40 * 2 = 80 ms
- Conclusion: 80 / 1000 = 8%. Although this game is creating a lot of garbage, the collector is running very fast so this is not causing performance problems. You should look elsewhere for the cause of your slowness.
- Garbage collections in the last second = 3
- GC Latency Time = 30
- Total GC time = 3 * 30 = 90 ms
- Conclusion: 90 / 1000 = 9%. Again garbage collection is only a small percentage of the overall CPU usage, but this time each collection is taking long enough that it could be causing some visible glitching. If your game is running at 60 frames per second, you only have 16 milliseconds to complete each Update/Draw cycle, so spending 30 milliseconds in the garbage collector is going to make you miss a frame. These figures are ok for a game that is targeting 30 fps, but worrying if you want to run at 60.
- Garbage collections in the last second = 30
- GC Latency time = 25
- Total GC time = 30 * 25 = 750 ms
- Conclusion: 750 / 1000 = 75%. Yikes! This game is totally bottlenecked by the garbage collector, and needs to do some serious work to cut this down.
Step 3: twin paths to nirvana
To be continued...