tags:

views:

858

answers:

3

I need to run my game loop with very accurate timing. I am trying to use NSTimer to do this, and I am getting ok results, but there is a bit of drift. When NSTimer fires does the next time event start counting when the handler finishes or does it start counting straight away. If the former is it reasonable for me to use setFireDate to try to offset the next timer firing - when I tried this things seemed worse.

My timer is set to fire every 44ms and I would like to stop it drifting by more than 20ms. If it does drift I would like to correct it for the next fire. Is this a reasonable thing to try and do with NSTimer?

+5  A: 

I don't think NSTimer will give you "very" accurate timing. It fires on the run loop, so if it's in your main thread then it'll get delayed by everything from UI updates to event handling.

Daniel Dickison
when I say very accurate, I mean I don't want it to drift by more than say 20ms. my timer fires every 44ms, when it does drift I would like to correct the next firing. In fact I think I'll update the question with this info
Ian1971
The doc for NSTimer says the timing is always based on the original interval from when it's started. That means it shouldn't "drift", but it can have "jitter". The doc also claims an effective resolution of 50 - 100 ms.
Daniel Dickison
Hmm that is probably not an accurate enough resolution for me. I have managed to get the variance down quite a lot by adjusting the fireDate based on time since last fire. Maybe I need to look into usleep() timing mentioned by Peter Hosey.
Ian1971
+4  A: 

You might try creating a thread and scheduling your timer on that thread's run loop. Having that timer as the only thing on that run loop should limit the number of things that can interfere with it.

If that doesn't work, well, you'll already have it working on a thread, so you may as well switch to a usleep() loop.

Peter Hosey
I am going to try this. It will be a while before I can report back though
Ian1971
+1  A: 

Also keep in mind that the NSTimer documentation states:

Because of the various input sources a typical run loop manages, the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds. If a timer’s firing time occurs while the run loop is in a mode that is not monitoring the timer or during a long callout, the timer does not fire until the next time the run loop checks the timer. Therefore, the actual time at which the timer fires potentially can be a significant period of time after the scheduled firing time.

Dimitris