Dealing with iPhone OS background processes

Discussion in 'Public Game Developers Forum' started by emitcollect, Jul 24, 2009.

  1. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    #1 emitcollect, Jul 24, 2009
    Last edited: Jul 24, 2009
    Hi folks,

    I'm getting ready to submit my first game to the App Store, but I'm hung up on maintaining a smooth framerate on the first-gen iPhone using OS 3.0. There are occasional hiccups that occur about once per minute, undoubtedly due to OS background processes kicking in (this will happen even when there's not much going on in the game). Otherwise, the game runs at a steady 60 fps.

    Implementation-wise, I'm creating a separate thread to handle the game logic and rendering, which relies entirely on VBL sync blocking to prevent it from going faster than 60fps. I've also got Compile for Thumb turned off, -ffast-math and O3 optimization enabled (also tested with O2), as well as auto-vectorization. All the game logic is done in straight C, minimizing the use of Objective-C objects and even C function calls. CocosDenshion is being used to handle the audio (although this is the only part of Cocos2D that I'm using), with music in MP4 format (mono, 96kbps), small .wavs for sound effects, which are used sparingly. Calls to OpenGL are also minimized, including state changes, and I'm using interleaved data wherever possible.

    I've tried using frame skipping as described in iPhone Games Projects, but this doesn't appear to have helped. The only thing I can think of doing at this point is to calculate everything's position based on elapsed time, but the hiccups seem long enough (say, a quarter to a half second) that this wouldn't effectively counter them.

    I've been using PewPew as a basis for comparison, and it doesn't seem to suffer from background process hiccups nearly as much. Are there any techniques I should be using to deal with them? Should I force the thread to sleep until it's time to process the next tick? Any suggestions would be appreciated.
     
  2. slipster216@gmail.com

    [email protected] Active Member

    Mar 11, 2009
    39
    1
    0
    Game Developer
    Boston, mass
    I've noticed small hickups in frame rates on all iphone games if you haven't rebooted in a while. However, if they're more than a few frames you have something else going on. I'd run things in shark and see if it turns up any particular culprit. Also, put a break point in the app delegate function that's called when the phone needs to free up memory - if you're pushing your memory usage, it might be getting triggered and could definitely cause hickups.

    Also, it's always wise to code things in a frame rate independent manner regardless of if your hitting frame rate on what you expect to be your low end device. I've also noticed that spawning many different threads can have a performance impact; so only create new threads when you really need to run something asynchronously.
     
  3. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    Jason, thanks for the tips. I did some profiling and decided to experiment with forcing the thread to sleep. I've got to play around with the numbers some more, but so far this seems to have greatly reduced the incidence and severity of the hiccups. Now they only tend to occur when the action gets really hairy, which is what I'd expect. I'm thinking I can track the overage on long-running ticks to dial down the framerate so there's still time leftover for background processes.
     
  4. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    #4 emitcollect, Aug 1, 2009
    Last edited: Aug 1, 2009
    Revisiting this, it seems that the thread sleeping strategy gave illusory results, as hiccups would eventually start up again, regardless of how I configured the sleeping intervals. So I went back to using an NSTimer on the main thread (at a 1.0/66.0 interval) and, so far, it appears to play better with background processes. However, that screws things up on a 3GS, so I'm using Erica Sadun's UIDevice-hardware code to start the game with timers on older hardware and threads on newer hardware (3GS, iPod touch 2G).

    Edit: Scratch that. It behaved smoothly for a good while but then started hiccuping again. Totally baffling, because the degradation doesn't depend on how long the device has been on or anything.
     
  5. Anders

    Anders Well-Known Member

    Feb 3, 2009
    1,634
    0
    0
    Co-owner and CTO at Color Monkey
    Sweden
    The framerate hickups started on 3.0, before that we had no problems at all. We're using timers as well.

    I hope Apple will release 3.1 sometime soon and fix all those bugs 3.0 came with (which we devs usually are blamed for when the games behave oddly).
     
  6. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    Ah, that's a relief to hear. I've spent a good portion of my life now trying to get rid of them, thinking I must have deficient knowledge of threads and such. Glad to know it isn't my fault!
     
  7. Anders

    Anders Well-Known Member

    Feb 3, 2009
    1,634
    0
    0
    Co-owner and CTO at Color Monkey
    Sweden
    Well it could depend on other things too! Atleast on my device 3.0 is behaving very oddly, and it was fine before. I try to ignore the performance issues for our next game right now and take care of if when 3.1 is out, cause right now you will have to go the blind route trying to fix things (runs at 60+ fps full 3D with the occasional stutters as you mentioned, then it goes down to about 30).

    You're using OpenGL right?
     
  8. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    Yup, OpenGL! And yeah, I'm sure something else could be contributing to the performance issues, because the stutters seem a bit more noticeable in my game than in others. Part of that is probably because my updates aren't framerate independent, but I implemented that briefly and it didn't make that much of a difference.

    Have you only noticed stutters on an iPhone 1G? I haven't been able to personally observe my game running on a 3G, but a friend who owns one said he hadn't noticed any issues. I'm also guessing the iPod touch 1G doesn't run the same background processes as the iPhone, and would be less prone to stutters.
     
  9. Anders

    Anders Well-Known Member

    Feb 3, 2009
    1,634
    0
    0
    Co-owner and CTO at Color Monkey
    Sweden
    Yup, you really should do it framerate independent. It should help with stutters, but more importantly it will make it run fine on all devices, which is important since the performance difference between the iPod Touch 1G and the 3GS is huge!

    Dunno. We don't have that many devices, and we would need the double if we would have each device pre-loaded with each software version (i.e. 1.x, 2.x, and 3.x). I don't think we have an iPhone 1G with 3.0 (I think we have 2.2.1 on that one). Is it possible to downgrade the software btw?
     
  10. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    I'll give it a shot for the next point release. Aside from the hiccups, it runs at a solid 60fps on an iPhone 1G, so I'm hoping it'll run fine on an iPod touch 1G. The only reason why I'm reluctant to make it framerate independent is because it might create subtle errors with the collision code. (Maybe not, but I didn't want to risk it this close to release.)

    Ah, so which device with 3.0 have you noticed the stutters on? The 3G?

    I've looked into downgrading the software, but couldn't get it working. There's a technique where you put the device in a certain mode and then Option-Restore with older firmware, but I think this requires an older version of iTunes.
     
  11. GlennX

    GlennX Well-Known Member

    May 10, 2009
    761
    0
    0
    UK
    Have you tried running your game in Airplane mode, for me this eliminates the stutters. Obviously this is no solution but it will tell you if it's background tasks messing with your framerate. I can get most of the Airplane mode benifits by switching my mail to 'manual'. I was running on 'hourly' (in an attempt to improve battery life) but I think this might be the very worst setting for the stutters as every time you wake the phone to play your game, the device seems think "I'm awake now, I better just check for mail". It's a pain but one school of thought is that people using their devices as serious gaming devices will have seen all of this before an be running with apropriate settings.

    One other trick is to move presentRenderbuffer to just before your openGL section rather than just after it. This only works on the device (you have to do it after on the simulator) so you will have to use conditionsl code on TARGET_IPHONE_SIMULATOR
     
  12. Anders

    Anders Well-Known Member

    Feb 3, 2009
    1,634
    0
    0
    Co-owner and CTO at Color Monkey
    Sweden
    Well you will have to make it framerate independent at some point, or else the game will run twice as fast on the 3GS ;) And changes like these are usually better done early.

    Yup the 3G (that's the one I'm currently developing on).
     
  13. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    Do you perform your update (game logic) at the beginning of your run loop, then presentRenderbuffer, then do OpenGL calls? Or is presentRenderBuffer the very first part of your run loop? (I'm assuming you run this all in the same thread, either the main thread or a second thread.)

    I actually still get hiccups in airplane mode....
     
  14. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    #14 emitcollect, Aug 2, 2009
    Last edited: Aug 2, 2009
    So I stopped background music from playing, and the game appears to run flawlessly. That doesn't necessarily mean playing music is the problem, but since the hiccups occur regardless of how much is going on game-wise, that makes me suspicious.

    Edit: Augh! Nevermind. Seems like I was getting illusory results yet again.
     
  15. drunknbass

    drunknbass Well-Known Member

    Nov 8, 2008
    128
    0
    0
    i know 60 fps is a nice number to target, but i have found personally to limit to a fps that you can meet 90% of the time, and also base all animations off a delta time.

    a steady framerate will appear much smoother than one at 60fps that dips down every once in a while, it makes it seems jerky in comparison :D
     
  16. 99c_gamer

    99c_gamer Well-Known Member

    Mar 23, 2009
    659
    0
    0
    I dont even have a compile for thumb option in my xcode v3.1.3. Could it be that you're using an older version of xcode?
     
  17. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    The game actually runs at 60fps +90% of the time, and even when it dips a little below that (like to 54fps), it's pretty acceptable. But when it hiccups (like a quarter-second pause), it sucks. Fwiw, I did try running it at 30fps, but it wasn't nearly as nice to look at. I'm going to post a video of it tomorrow so you can see it in action. It's not GPU-intensive at all, and only CPU-intensive when there are lots of enemies in play.

    So far, I've gotten the best, most consistent results from using an NSTimer on older hardware. That seems to give occasional slowdown/stutters rather than hiccups (I consider a "stutter" to be less severe than a "hiccup" :)). It seems pretty acceptable to me playability-wise, so that's the configuration I ended up submitting to the App Store.

    I'm really hoping this is just an issue with OS 3.0 that gets solved with 3.1. Otherwise my next game will definitely target a lower framerate.
     
  18. emitcollect

    emitcollect Well-Known Member

    Jul 22, 2009
    61
    0
    0
    I'm running 3.1.3 as well. It should be in your Project Settings under the GCC 4.2 - Code Generation section.
     
  19. 99c_gamer

    99c_gamer Well-Known Member

    Mar 23, 2009
    659
    0
    0
    #19 99c_gamer, Aug 2, 2009
    Last edited: Aug 2, 2009
    ok I found it. Its only for the device and not simulator. Will I get a good speed improvement if I uncheck that?

    nevermind. Just read that it's a memory tradeoff which I definitely cant afford.
     
  20. GlennX

    GlennX Well-Known Member

    May 10, 2009
    761
    0
    0
    UK
    I moved

    [context presentRenderbuffer:GL_RENDERBUFFER_OES];

    form it's normal position at the end of my openGL section to right at the start.

    It doesn't change the structure of the openGL code at all but theoretically helps concurency as your non-graphics code gets to do it's stuff while the hardware is processing the render queue. That said I'm not so sure it makes much of a difference now. Maybe something changed in the drivers so the trick either doesn't work or concurency is achieved regardless.

    On the subject of turning "compile for thumb" off. Have you tried this?, does it really run out of memory?, I found it a huge win when I turned it off.
     

Share This Page