Tacking performance degradation

Started by
4 comments, last by CdrTomalak 10 years, 12 months ago

Hi,

I'm at a stage where my 2D game engine (starting with pacman) is fairly stable. What I've not done though is looked into performance.

By running the profiler, I have optimised my render method quite well, but I still get a degradation in performance after say 30 seconds of game-play.

My first question is, will the profiler pick up things like degradation, or does it take an average of the ticks per function? I am using SharpDevelop by the way.

The second question is, what is the recommended strategy for tackling performance problems? My current understanding is that due to garbage collection, I don't need to worry about unreferenced objects too much. But is it not the case that even the garbage collector might not be able to keep up if one is too inefficient?

I could opt for a full code-review, function by function, to ensure that things are running efficiently. For example, I have not taken care to dispose of objects when they are clearly not of use. Presumably this will help? I have been concentrating on core functionality actually working up to this point, and game logic - but the time has come to make this thing run as slick and efficiently as possible.

Any comments are most welcome. It would just be interesting to hear how people go about such things if they notice a degradation in performance in a language that has garbage collection.

Thanks in advance! biggrin.png

Advertisement

I've decided to count the ticks between each function call in the main game loop. I have also set up a struct to hold a record of the average ticks taken to execute each function of the game loop.

Analysis of the resulting log file after a game session should reveal the problem function. This seems to be the most fail-safe way of avoiding costly code-reviews of the whole game in terms of data structure usage.

First of all, let me express my congratulations that you managed to stay away from optimizations up till this point, since now you have something up&running and just need to clean it up a bit.

Is this C# ? What platform are you getting the slowdowns on ? I am asking since under .NET, the GC runs in a separate thread on PC and you can experience the GC-caused slowdowns only on XBOX.

Also, note that you don't want to write to a log file 10 times during a single frame. You want to collect the data in RAM and only dump the data to physical file after you are done with profiling.

If it is C#, there are countless threads on XNA forums (of MS) about what does and what does not leak memory under C#. That list is pretty long and some of the stuff you find there is really suprising.

I will, however, mention No1 suspect and that is the String class. Whichever way you use it, leaks incredible amount of memory (so just use StringBuilder).

On XBOX, even if all you do is this single line every frame : String s1 = s2+s3; it will cause your game to halt for half a second every ~5 seconds.

There are .NET profilers, that will run alongside your game and will tell you exactly, each frame, how much memory has been leaked and you can see the moment when the GC runs. The name of that .NET profiler , unfortunately, escapes me at the moment.

VladR My 3rd person action RPG on GreenLight: http://steamcommunity.com/sharedfiles/filedetails/?id=92951596

My first question is, will the profiler pick up things like degradation, or does it take an average of the ticks per function? I am using SharpDevelop by the way.

What is degradation? Measure performance before, then measure it after. Is it worse? Then I guess you just measured degradation!

Any comments are most welcome. It would just be interesting to hear how people go about such things if they notice a degradation in performance in a language that has garbage collection.

I'm not sure the fact that it has garbage collection matters. If performance degrades over time, my guess would be that you're still processing game logic on entities that aren't part of the game anymore. If you have bugs in your code, these "leaks" can happen whether or not you're using a language with garbage collection.

At any rate, if this is on a PC, I kind of doubt you would be affected by garbage collection pauses.

I have not taken care to dispose of objects when they are clearly not of use. Presumably this will help?

If an object follows the Dispose pattern (typically objects that hold onto native resources, like files or GPU resources), then yes - you absolutely must Dispose of it when you no longer need it.

Analysis of the resulting log file after a game session should reveal the problem function. This seems to be the most fail-safe way of avoiding costly code-reviews of the whole game in terms of data structure usage.

Yes. Essentially you are doing a binary search to narrow down the possible problems. You might also want to put in debug switches into your game so you can enable/disable certain components while the game is running. This will let you see live how they affect performance.

You might also want to put in debug switches into your game so you can enable/disable certain components while the game is running. This will let you see live how they affect performance.

This.

8 yrs ago I spent about 10 minutes putting few boolean flags into my engine (bRenderTerrain, bRenderEnvironment, bRenderCharacters, bProcessAI, bProcessInput, ...) and those have been the best spent 10 minutes on the engine. Ever.

Because to this day, if performance is suddenly taking a hit, in the middle of testing, it takes me 10 seconds to turn on/off certain/all components and figure out which one is the one. No debugging, no breakpoints, no profiling (unless absolutely needed). I worked on multiple games in that timeframe and on multiple platforms, but this Turn On/Off feature is especially useful on non-PC platforms.

So, put few if (bComponentOn) lines into the code, connect the KeyHandlers and enjoy !

VladR My 3rd person action RPG on GreenLight: http://steamcommunity.com/sharedfiles/filedetails/?id=92951596

Vlad and phil - thank you very much for the replies to this thread!!

I have since looked at the Render() method and spotted some obvious inefficiencies, both with string usage, and texture object declaration - the latter providing a gain of 30% efficiency, and the degradation has seemingly gone!

Vlad - good call on putting switches in. My game is laden with debug flags to turn logging on for methods, although I don't have switches to by-pass methods yet. I'm not sure my game loop is designed to be able to cope with that - although this is interesting because maybe it should be.

For now I'm back on track. I had no idea about StringBuilder until now. Thanks for the tips.smile.png

This topic is closed to new replies.

Advertisement