How to improve a game fps

Started by
5 comments, last by larspensjo 11 years, 1 month ago

Source from DigiPen :

In the past, Luedke has been something of a game project “fixer.” For example, about five months before Microsoft’s Forza Motorsport 2 racing simulator was scheduled to ship in 2007, the game was running at an unplayable two frames per second. As a performance expert within Microsoft Game Studios’ shared technology group, Luedke went in to try and rescue the project. He found the developers had been creating the game’s interconnected systems in isolation, with little to no regard for the game’s overall performance.

“There was one person who went and built the mini map system, or one person who built the skid-marks-on-the-track system,” Luedke says. “And then when they finally had to get their first playable prototype together, everybody kind of turned on all the systems at once.”Fortunately, through cutting certain features and optimizing others, Luedke managed to help the team bring the game back up to speed (in this case, 60 frames per second). And Forza 2 went on to be a commercial and critical success.

So is the strategy to not turn all system at once but to turn them when they need to be for the game to run 60 fps? I only have 1 month experience with game programming in Java but I found this fascinating of how they go about optimizing the game's performance. Is this anything remotely the same if someone programmed a 2d or 3d game in Java and wanted to optimized its performance in speed?

Advertisement

through cutting certain features and optimizing others

The way I read it, is they just cut out some features, and optimized other features.

So I don't think they turn on and off features in game as they are needed, but rather they just removed them.

I think the lesson is to test all systems together more often than once everything is done. Although this is probably impractical with a really big game where multiple teams are working on very different aspects and have different priorities. But as a single developer, or if you have a small team, it's probably doable.

From my tiny experience of developing games at spare time, I had once terrible performance. My solution to the issue was to cache rotated images instead of recalculating them each frame. I was dealing with png files, and rotating them few degrees. So I had original image at 0 degrees, and added caching of same image at <current> degrees.

In my professional experience with enterprise software, you usually design it really really really well. Than you code it really well, code review, performance test. And the performance test has to be a subset of permissible time. So for example if you're supposed to process 100 GB of data per hour, and you used up 30 min in your part, than either you're allowed to spend 50% of time in your area, or you gotta go back and look at design + programming.

http://www.mildspring.com - developing android games

through cutting certain features and optimizing others

The way I read it, is they just cut out some features, and optimized other features.

In my professional experience with enterprise software, you usually design it really really really well. Than you code it really well, code review, performance test. And the performance test has to be a subset of permissible time. So for example if you're supposed to process 100 GB of data per hour, and you used up 30 min in your part, than either you're allowed to spend 50% of time in your area, or you gotta go back and look at design + programming.

Thanks!

I think this is similar to what you’re saying in the original post. One of the techniques I’ve found to be useful in a lot of cases is to stagger non-essential update methods when they don’t have to run every update loop and you don’t want them to all run at the same time. I’m making an RTS right now, and I’ve got some methods that have to run every frame for every unit (movement, collision detection, etc.) but there’s also for example a “scan for nearby enemies” method that is quite time consuming, but there’s no reason to call it every update. Instead of finding nearby units in each main update loop, each unit keeps a list of nearby units that is updated every 30-40 frames, or often enough that the unit will always have an accurate list of units within firing or collision range.

Part of the solution is making sure that you aren’t unnecessarily repeating tasks, for example collision and weapon firing both need a list of nearby units, so instead of finding a new list of units within each method, you can do a single search and then share the data between both methods. (There’s a good chance this can be an issue with modular components developed by different teams, which is why you should always make sure your different components aren’t repeating the same sub-task when they don’t have to.) It’s also helpful to determine which tasks are absolutely necessary (movement collision detection, etc.) while taking the more advanced tasks like pathfinding or strategic AI and realizing when you can get away with doing them once and then only checking periodically that the initial result is still valid.

I think this is similar to what you’re saying in the original post. One of the techniques I’ve found to be useful in a lot of cases is to stagger non-essential update methods when they don’t have to run every update loop and you don’t want them to all run at the same time. I’m making an RTS right now, and I’ve got some methods that have to run every frame for every unit (movement, collision detection, etc.) but there’s also for example a “scan for nearby enemies” method that is quite time consuming, but there’s no reason to call it every update. Instead of finding nearby units in each main update loop, each unit keeps a list of nearby units that is updated every 30-40 frames, or often enough that the unit will always have an accurate list of units within firing or collision range.

Part of the solution is making sure that you aren’t unnecessarily repeating tasks, for example collision and weapon firing both need a list of nearby units, so instead of finding a new list of units within each method, you can do a single search and then share the data between both methods. (There’s a good chance this can be an issue with modular components developed by different teams, which is why you should always make sure your different components aren’t repeating the same sub-task when they don’t have to.) It’s also helpful to determine which tasks are absolutely necessary (movement collision detection, etc.) while taking the more advanced tasks like pathfinding or strategic AI and realizing when you can get away with doing them once and then only checking periodically that the initial result is still valid.

good point. only do checks if they are necessary.

From the original post, what they were saying is that when every feature was completed and enabled, the game slowed to a crawl. They then optimized it by cutting unnecessary features (or lower priority features) and by optimizing other features. It was also suggesting that the team got into the mess they did because they were all independently developing their features without considering the performance of the overall game.


As far as optimizing games there are lots of approaches (all of which are important for cutting edge games):
-Algorithmic optimizations (i.e. spatial partitioning, staggered updates, other algorithmic optimization).
-Data optimizations (improving load hit store/cache misses)
-Multi-processing (going wide across multiple processors/threads), and architect your gameloop to ideally never have to wait for a thread to finish (not always possible, but a goal to strive for).


Data layout and memory access are actually a big factor in optimizations that a lot of people don't consider. Cache misses and load hit store problems can negatively affect performance quite a bit.

And the ever important one:

Do measurements. Don't measure individual components in FPS, measure them in ms. Find what the main components of the drawing are, and measure each of them. Just be careful not to measure the system time on the PC, you have to measure the time as reported by the graphics card. These are usually not the same as the graphics card will draw things in the background.

Of course, CPU-bound algorithms have to be measured using PC system time.

During development, you should continuously do these measurements and log them. That way, you get a history of changes, and can easily detect when something went wrong.

[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

This topic is closed to new replies.

Advertisement