Re: Synchronize timer with internal clock
Re: Synchronize timer with internal clock
- Subject: Re: Synchronize timer with internal clock
- From: Chris Kane <email@hidden>
- Date: Sun, 16 Mar 2003 13:03:21 -0800
On Friday, March 14, 2003, at 15:53, John Timmer wrote:
While on the subject of timers vs. the internal clock:
How accurate are timers expected to be? I had coded something where,
in
order to keep a clock display reasonably close to accurate, I was
firing a
timer every 5 seconds. This seemed wasteful and inelegant, so I
decided to
synchronize with the minute and fire the timer every 60 seconds.
Doing so
revealed a steady downward creep when I logged the firing of the timer
(see
below). I kept going, hoping that eventually it would tick up to
compensate, but instead it eventually wrapped around the minute,
leaving my
clock 59.998 seconds off.
Is there any way around this, or should I be checking the accuracy of
the
timer every time through and invalidating it when necessary?
John
Note the steady reduction in when the timer fired:
2003-03-14 18:31:00.453 Weather View[7155] updating time
2003-03-14 18:32:00.409 Weather View[7155] updating time
2003-03-14 18:33:00.401 Weather View[7155] updating time
2003-03-14 18:34:00.393 Weather View[7155] updating time
2003-03-14 18:35:00.385 Weather View[7155] updating time
2003-03-14 18:36:00.377 Weather View[7155] updating time
2003-03-14 18:37:00.369 Weather View[7155] updating time
2003-03-14 18:38:00.361 Weather View[7155] updating time
2003-03-14 18:39:00.353 Weather View[7155] updating time
2003-03-14 18:40:00.349 Weather View[7155] updating time
This depends in large part on the OS's estimate of the clock rate of
the system clock, which varies in "goodness" by OS release and
hardware. I wrote a little test and got this (on a 500 MHz DP):
2003-03-16 12:52:22.001 a.out[11586] 69540742.000053
2003-03-16 12:52:23.001 a.out[11586] 69540743.000065
2003-03-16 12:52:24.001 a.out[11586] 69540744.000055
2003-03-16 12:52:25.001 a.out[11586] 69540745.000050
2003-03-16 12:52:26.001 a.out[11586] 69540746.000058
2003-03-16 12:52:27.001 a.out[11586] 69540747.000060
2003-03-16 12:52:28.001 a.out[11586] 69540748.000056
2003-03-16 12:52:29.001 a.out[11586] 69540749.000062
2003-03-16 12:52:30.001 a.out[11586] 69540750.000063
2003-03-16 12:52:31.001 a.out[11586] 69540751.000056
2003-03-16 12:52:32.001 a.out[11586] 69540752.000066
Your tenth of a second in 10 seconds (1 part in 100) seems quite bad; I
don't think I've seen something that bad since the old PowerMac 8500.
Of course, there are other effects too. The NTP daemon will drive your
calendar clock (what NSLog() and CFAbsoluteTime() are showing) faster
or slower than "true" while it is trying to synchronize your clock to
the actual time off the Internet (rather than do a step adjustment,
which it only does in extreme cases). For example, the calendar clock
might only advance 950 milliseconds every second during adjustment.
Usually, if you're connected to the Internet, NTP is able to get things
in line within an hour with small adjustments. But even then, if you
system clock is wildly different from "true", the calendar clock may
advance at a different apparent rate than the system clock. Timers are
fundamentally based off the system clock for their timing, even though
the API is in terms of the calendar clock.
Try the test program below and see what you get.
Chris Kane
Cocoa Frameworks, Apple
#import <Foundation/Foundation.h>
@interface TEST : NSObject @end
@implementation TEST
- (void)timer:(id)x { NSLog(@"%f", CFAbsoluteTimeGetCurrent()); }
@end
#define INTERVAL 1.0
#define roundUpTime(T, I) (floor((T) / (I)) * (I) + (I))
#define dateForNextInterval(I) [[NSDate alloc]
initWithTimeIntervalSinceReferenceDate: roundUpTime( [NSDate
timeIntervalSinceReferenceDate], (I))]
int main() {
NSTimer *myTimer = [[NSTimer alloc]
initWithFireDate:dateForNextInterval(INTERVAL)
interval:INTERVAL target:[TEST new] selector:@selector(timer:)
userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:myTimer
forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
exit(0);
}
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.