Alternative to NSTimer

Member
Posts: 166
Joined: 2009.04
Post: #31
DoG Wrote:I think people are misunderstanding NSTimer. It's not a hard-realtime timing solution. You're supposed to set the timer to fire faster than your intended framerate, and check the time in your callback. If it's running too fast, you'd just do nothing, and wait for the next callback. If the timer runs slower than intended, it's because device is busy doing something else.

The custom runloop doesn't do much else, only in a roundabout fashion. A separate thread only helps if the main thread is blocked on IO or other transactions which leave the CPU idle.

A custom loop lets you control the timing ... in other words , I have a bit more control over how much time is being spent handling events vs rendering/logic updates.
Quote this message in a reply
Member
Posts: 24
Joined: 2009.02
Post: #32
DoG Wrote:...You're supposed to set the timer to fire faster than your intended framerate, and check the time in your callback. If it's running too fast, you'd just do nothing, and wait for the next callback.

Supposed to? I don't see this advice in the class reference for NSTimer. Your approach has become a common one to get around timing inconsistencies, but it's hardly the best solution.

I don't understand what the aversion is to using a thread. It's far easier than using a timer and having to resort to oversampling (which is what you're doing) to get better resolution.

If you're happy with your approach, cool. Each to his own.
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #33
mpatric Wrote:Supposed to? I don't see this advice in the class reference for NSTimer. Your approach has become a common one to get around timing inconsistencies, but it's hardly the best solution.

I don't understand what the aversion is to using a thread. It's far easier than using a timer and having to resort to oversampling (which is what you're doing) to get better resolution.

If you're happy with your approach, cool. Each to his own.

It's a given that you are indeed supposed to use NSTimer in this way, due to the very nature of its workings. NSTimer is not hard realtime, hence it does not, and cannot, make any guarantees on the minimum time it takes to fire.

If your timer runs faster than you need it, it means the CPU is free, so no harm done, and the timer frequency will decrease as the CPU load (or rather, time spent in the thread elsewhere) increases. Running a tight loop on a thread and using sleep() doesn't do any better, as sleep() can also take significantly longer to return than the intended time when the other threads are busy.

In summary, running a polling main loop in another thread has no benefits over running a proper run loop in another thread, which in turn only results in better CPU utilization if the main thread spends a lot of time being blocked.

Adding additional threads is always tricky, as you always need to make sure the threads don't step on each others toes.

I am not sure what leads people to believe that they can outdo the CF/NSRunLoop mechanism with their own nearly equivalent, but not quite as efficient, contraptions.
Quote this message in a reply
Member
Posts: 166
Joined: 2009.04
Post: #34
DoG Wrote:I am not sure what leads people to believe that they can outdo the CF/NSRunLoop mechanism with their own nearly equivalent, but not quite as efficient, contraptions.

You know people don't do this to make their lives more interesting - obviously, NSTimer is not enough for them.
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #35
warmi Wrote:You know people don't do this to make their lives more interesting - obviously, NSTimer is not enough for them.

I am inclined to believe people just don't understand what's going on, in connection with the NIH syndrome.
Quote this message in a reply
Member
Posts: 25
Joined: 2009.05
Post: #36
DoG Wrote:I am inclined to believe people just don't understand what's going on...
My step time takes 0.066s insted of 0.033s. What is going on?
NSTimer behave not as it supposed to behave by any one in mind. Why NSTimer just miss function call? This is unacceptable behavior for timer, and that is why ppl moving out of NSTimer.
Quote this message in a reply
Member
Posts: 40
Joined: 2009.05
Post: #37
I wrote a quite test program running a timer 120 times a second to see what sort of variation in time period I got.

The app was the basic view template application with the timer scheduled using:

[NSTimer scheduledTimerWithTimeInterval:1.0/120.0 target:self selector:@selector(myTimerSmile userInfo:nil repeats:YES];

The timer behaves nicely when there is no user interaction going on. The timer function get's called approximately every 0.008333 seconds. Things get a lot more variable when you have the user touching the screen.

Here's my result running over a 30 second period:

No touches

0.006008,3
0.006832,3
0.007655,1763
0.008479,27
0.009302,3
0.010126,0
0.010950,0
0.011773,0
0.012597,0
0.013420,0
0.014244,1

Touching, tapping swiping the screen etc

0.002097,5
0.003344,25
0.004591,29
0.005838,247
0.007085,1258
0.008332,1726
0.009579,252
0.010826,27
0.012073,24
0.013320,5
0.014567,1

Multi-touch enabled with touching tapping and swiping the screen

0.002818,9
0.003929,14
0.005039,23
0.006150,202
0.007261,2684
0.008371,433
0.009482,189
0.010593,21
0.011704,14
0.012814,9
0.013925,1
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #38
ShiftZ Wrote:My step time takes 0.066s insted of 0.033s. What is going on?
NSTimer behave not as it supposed to behave by any one in mind. Why NSTimer just miss function call? This is unacceptable behavior for timer, and that is why ppl moving out of NSTimer.

If your timer callback takes longer to do its work than the intended step time, how do you expect it to be called sooner again?
Quote this message in a reply
Member
Posts: 25
Joined: 2009.05
Post: #39
DoG Wrote:If your timer callback takes longer to do its work than the intended step time, how do you expect it to be called sooner again?

I was expecting immediate recall right after finishing callback, with or without spending time on system services. Preferebly with.
Quote this message in a reply
Member
Posts: 166
Joined: 2009.04
Post: #40
DoG Wrote:I am inclined to believe people just don't understand what's going on, in connection with the NIH syndrome.

I doubt it .... what's there not to understand. The first thing most people do is to use NSTimer ... and they only go for alternatives when they encounter problems.
NSTimer is a generic GUI message loop style timer which is being invoked based on certain priorities which may or may not be in line what people want for certain applications.
Quote this message in a reply
Member
Posts: 24
Joined: 2009.02
Post: #41
ShiftZ Wrote:I was expecting immediate recall right after finishing callback, with or without spending time on system services. Preferebly with.

The class reference for NSTimer says:

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.

So, why would you expect it to call again when the documentation says it doesn't?
Quote this message in a reply
Member
Posts: 24
Joined: 2009.02
Post: #42
iamflimflam1 Wrote:I wrote a quite test program running a timer 120 times a second to see what sort of variation in time period I got.
...

Yep, this is why I use a thread.

Apple state the effective resolution of NSTimer is 50ms to 100ms, which is too high to maintain a stable (high) framerate. From the NSTimer class reference:

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.
Quote this message in a reply
Member
Posts: 24
Joined: 2009.02
Post: #43
DoG Wrote:I am not sure what leads people to believe that they can outdo the CF/NSRunLoop mechanism with their own nearly equivalent, but not quite as efficient, contraptions.

I used a NSTimer on one of my apps and eventually switched to a Thread as I could not resolve the occasional stuttering in the animation that I would get, particularly when there was lots of user input happening. I was very happy with the results, which is why I commented in this thread.

If a NSTimer based app does not exhibit any issues I would not suggest changing it.
Quote this message in a reply
Member
Posts: 25
Joined: 2009.05
Post: #44
mpatric Wrote:So, why would you expect it to call again when the documentation says it doesn't?
No matter why, the matter is "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.."
And this makes NSTimer completly unsuitable for games.
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #45
mpatric Wrote: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.

Not sure where that is coming from, but that statement isn't universally valid, and most certainly you can get much finer granularity from a timer, depending on the environmental factors.

Also, I think there's a confusion about what I am saying.

There's two things:
A) use of a second thread
B) use of a custom loop

You can do A) without doing B) by instantiating a run loop on the second thread. Since that run loop would not handle *any* other source than your timer, it should fire at the exact expected intervals, as long as your callback doesnt take too long.

If you have congestion on the main thread, then going to a second thread will help will help with the apparent jitter of the updates, but it will also increase latency, since whatever happens in the main thread and your game thread will have to be executed in parallel, so both tasks will take longer than when running alone. So there's always a trade-off.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  NSTimer fine, CADisplayLink having some issues monteboyd 5 9,656 Aug 31, 2010 07:05 PM
Last Post: Skorche
  NSTimer hiccups/choppy/jerky jeonghyunhan 2 2,893 Sep 24, 2009 07:35 PM
Last Post: jeonghyunhan
  Using an NSTimer to progressively draw a view StevenD 4 4,431 May 14, 2009 07:57 AM
Last Post: StevenD
  OpenGL render loop - NSTimer vs rendering thread smallstepforman 27 23,306 Feb 2, 2009 10:22 AM
Last Post: ThemsAllTook
  Alternative Input/Control Ideas chrisco 8 4,393 Aug 6, 2008 03:21 PM
Last Post: bruss14