Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Every 5-10 minutes there's a noticeable frame-rate hiccup in my game. Other than that my game runs very smoothly - again it's just one quick little jump every 5-10 minutes. Is this something I need to iron out or is it not a big deal?

How can I find what's causing this glitch? Is there a specific instrument I should use?

Here's some additional info:

  • It happens less on an iPhone 4 compared to a 3GS.

  • All my game objects use dynamic memory allocation with the default new and delete operators. I'm not using shared pointers. There are no memory leaks.

  • The game is of the shmup genre.

share|improve this question
    
Do you have any news or deletes inside the game loop? And are you using something like std::vector that could spontaneously start a large copying process? –  michael.bartnett Feb 14 '12 at 23:38
    
yes there are a bunch of news and deletes in the game loop. and yes I use a lot of std::vectors. i'd much rather deal with the vectors than try to do custom memory management. actually one thing i was curious about outside the obvious - i store all my vertices in a vector. i clear my vertices vector every frame and then push back all the new vertices and then render. would that be something? ...but that doesn't sound like it has much to do with copying. –  Ryan Feb 15 '12 at 0:05
    
How much of a jump is it? I mean, how much time (in milliseconds) occurs between frames, when the frame rate hiccup occurs? –  Trevor Powell Feb 15 '12 at 7:50
    
If the number of vertices you push onto the vector every frame increases periodically, then std::vector may possibly need to resize its internal array. The memory management wouldn't be a big deal. Just use object pools, allocate everything up front (as you enter the main play state), so that way if you need a new object of some type you can just grab an unused one from the object pool. Pools are pretty simple to implement. You can make your own template class, or even just use a bunch of globally-accessible linked lists. to manage it. Profile before you do, Xcode provides profiling tools. –  michael.bartnett Feb 15 '12 at 8:31
    
It's a quick little jump, maybe .1 - .5 seconds. I have my elapsed time clamped at .15 seconds. regarding object pools, my main question is does composition affect that. let's say i'm newing up a component in a constructor that uses constructor args...i don't see how the pool will keep that flow in place. can i still call constructors when the objects are coming out of pools? –  Ryan Feb 15 '12 at 15:21
show 1 more comment

4 Answers 4

up vote 14 down vote accepted

One of the most important skills to learn as a programmer is how to locate and fix performance problems. The good news is that this process is easier today than it has ever been in the past. As mentioned in the comments, a frame rate stutter of 0.5 seconds is completely unacceptable for any game which demands reflexes from the player, so this is a great excuse to learn this skill that you'll use for the rest of your programming career.

My advice is that you ignore all the assumptions and random guesses that people are putting forward. You don't have to guess at the problem, you can just measure your own performance and know the problem for certain. For an iPhone game, all you have to do is run your game through Instruments. Just choose the menu option: Profile from the Product menu in Xcode.

Profile Menu Option

This will build your program, launch it on device, and then start Instruments. Instruments will pop up a window asking what sort of profiling you want to do. It'll look a little like this (note that I'm profiling a MacOS app for my example, as I don't have an iOS project on hand to use for screenshots. When you do this, you'll choose CPU Time Profiler under the iOS heading, instead of MacOS X)

Choose Trace Template

Then run your game until the stutter happens. After it does, go back to Instruments and hit the pause button. Instruments will look something like this:

Instruments interface

The horizontal graph along the middle is how much CPU time was being used over time. You can see that my game used extra CPU time while launching (which I've highlighted in a red box), and that there was a spike of processing time a little later on (highlighted in a green box).

Additionally, the display at the bottom shows where your game is spending most of its time. The most important numbers are the percentages, which I've highlighted in a blue box. In this case, you can see that 3.2% of my time is spent inside of a function called memmove. (If I opened that up, I could see where I was most often calling that function from)

Now, those numbers are from the full runtime of my program (about 30 seconds in my case. Yours might be five or ten minutes, or however long it takes for your stutter to happen). So if you have a half second pause in five minutes of game play, the culprit probably isn't going to show up with a high overall percentage in your profiles. But luckily, you can tell Instruments precisely which bit of the timeline you're interested in by using the Inspection Range tools:

Inspecting the spike

As you can see, I've now drilled down to see precisely what's slow at this specific point in my game. Looking at the output, we can see which bits of code are taking the most execution time. While 'memmove' was showing up as 3% of my time in total, in this bad performance spot, it's taking up more than 11% of my CPU time. In this screenshot I've expanded 'memmove', to show how you can see what functions called into the problem function.

Now in my case, what I'm using as an example isn't a real spike like yours; it's just me doing something that's a little more computationally expensive than when the game is idle; my game is still running at 60fps through this period. Yours would have a vastly taller peak in the graph, and instead of having a top item that's using 10% CPU, you'll probably have one that's using 50% or more. I've often seen spikes where a single function used 70% to 80% of CPU time.

Following these steps will help you determine -- with extreme accuracy -- exactly what it is that's using up time, so you'll know what part of your program to think about trying to optimise.

But if you can't figure out how to speed up that problem area (whatever it turns out to be), then do open another question to ask about how to improve that specific thing.

Finally, it's important to note that this answer is only barely scratching the surface of what Instruments can do. It is absolutely worth your while to look through Apple's documentation to learn even more options to drill more deeply into the performance metrics it can gather on your game.

share|improve this answer
    
+1 for your procrastination (and really the best answer here). –  Jonathan Dickinson Feb 16 '12 at 10:30
    
Thanks. I've been playing around with time profiler a bit and it is quite useful. One problem though is that when I run the time profiler instrument it introduces even more stutter which makes it difficult to see where the real problem lies. –  Ryan Feb 16 '12 at 19:11
    
That's true; Instruments is an intrusive profiler, which means that it does affect the behaviour of the program that it's profiling. Your stutter should still be easily visible in the graph, though, when it happens! –  Trevor Powell Feb 17 '12 at 8:09
add comment

The behavior sounds like garbage collection which is odd. I assume you're not doing any background loading or other stuff like that, or you'd have mentioned it.

The fact that iphone4 fares better than 3gs may either be because iphone4 has a faster CPU or the fact that it has more RAM ( http://www.labnol.org/gadgets/compare-iphone-4-with-iphone-3g/13855/ ).

Generally speaking, performing dynamic memory allocations in real-time applications is a no-no, so you should avoid it as much as possible. Keep buffers around, re-use them as much as possible. If you're using vectors, don't delete them, just empty (not resize) them.

share|improve this answer
add comment

Whether or not you need to fix that is up to you. On my projects, the definition of a show stopper has been whether or not it affects the gameplay or causes data loss. Is it something that would cause a player to crash their ship or end their game when it happens?, If this bug happens, does it nuke a player's game save?, etc.

You could try using the memory allocations instrument and see if you have any spikes in memory when that hiccup occurs. That was a problem in my last game - it would run smoothly like you've described, but hiccup after a while because I had run out of cached enemies to display, and the game engine loaded a few more up.

share|improve this answer
    
no, it doesn't affect game play at all. it's just a minor visual glitch. –  Ryan Feb 15 '12 at 15:27
add comment

Have you tried initializing your std::vectors to a large size when the program starts up?? If the frame rate hiccup is related to a vector resize inside the game loop, this may help identify the issue.
You could also log your vector size, calculated frame rate, and a time stamp to a ring buffer in memory as your program runs. The goal here is to see if there is something "magical" going on within your game loop when you detect the drop in frame rate.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.