Re: high accuracy timing options?
Re: high accuracy timing options?
- Subject: Re: high accuracy timing options?
- From: "Aaron Turner" <email@hidden>
- Date: Thu, 27 Mar 2008 11:23:11 -0700
On Wed, Mar 26, 2008 at 5:34 AM, Andrew Gallatin <email@hidden> wrote:
>
> Rather than re-inventing the wheel, have you tried to measure the
> accuracy of gettimeofday() on darwin? It will be much better
> than you expect.
>
> MacOSX/Darwin uses a really clever method to move most of the heavy
> lifting out of the kernel and into userspace for gettimeofday().
> The kernel sets up a "commpage" with an appropriate gettimeofday()
> function for the hardware you're on. It then shares timestamp
> information with this gettimeofday() implementation. This commpage is
> then mapped into your process, so when you call gettimeoday(), you use
> this clever version.
>
> At least in the ppc implementation, the library calls mftb, so the
> timing info on ppc should be both cheap and very accurate. I don't
> understand x86 asm nearly as well, so I can't say exactly what the x86
> implementation does.
>
> Anyway, check out the kernel sources to see what I mean:
>
> xnu-$VERSION/osfmk/ppc/commpage/gettimeofday.s
> xnu-$VERSION/osfmk/i386/commpage/commpage_gettimeofday.s
Hey Drew,
So I decided to do some benchmarking:
---- code ----
int
main(int argc, char *argv[])
{
u_int32_t count = 0, fail = 0, back = 0, i;
struct timeval sleep_until, now, last;
for (i = 0; i < 5; i ++) {
gettimeofday(&sleep_until, NULL);
sleep_until.tv_sec += 5;
gettimeofday(&last, NULL);
do {
count++;
gettimeofday(&now, NULL);
if ((now.tv_sec == last.tv_sec) && (now.tv_usec == last.tv_usec))
fail ++;
else if (timercmp(&last, &now, >))
back ++;
last.tv_sec = now.tv_sec;
last.tv_usec = now.tv_usec;
} while (timercmp(&now, &sleep_until, <));
printf("Ran gtod() %lu times in 5 seconds.\n", count);
printf("%f gtod()/usec\n", (float)count / 5000 / 1000);
printf("Failed to increment %lu times\n", fail);
printf("Back in time %lu times\n", back);
printf("-------------\n");
count = 0;
fail = 0;
back = 0;
}
exit(0);
}
---- code ----
gcc -O3 -o gtod gtod.c
Very interesting results:
Ran gtod() 68160730 times in 5 seconds.
13.632146 gtod()/usec
Failed to increment 63197136 times
Back in time 0 times
-------------
Ran gtod() 68386072 times in 5 seconds.
13.677215 gtod()/usec
Failed to increment 63418876 times
Back in time 0 times
-------------
Ran gtod() 68054635 times in 5 seconds.
13.610927 gtod()/usec
Failed to increment 63102535 times
Back in time 0 times
-------------
Ran gtod() 65948046 times in 5 seconds.
13.189610 gtod()/usec
Failed to increment 61147617 times
Back in time 0 times
-------------
Ran gtod() 68162385 times in 5 seconds.
13.632477 gtod()/usec
Failed to increment 63201624 times
Back in time 0 times
-------------
Interesting how gettimeofday() fails to increment around 90% of the
time. I guess technically incrementing 1/10 times while requiring
~13 times to measure a usec is good enough, but it's not giving me a
warm & fuzzy feeling. Running a tight gettimeofday() loop in my
application seems to have good results down to 8usec between events
(sending a packet), but after that things start getting skewed. I'm
not sure if its a resolution issue of the timing loop or what. May
just be one of those things where a RTOS is necessary to get any
improvement. Anyone know if OS X/Darwin has the equivalent of Linux's
RT scheduler extensions?
So far I was lucky about NTP not moving the clock backwards, but I
suppose that could be an issue. But since I'm not trying to land man
on the moon or other dangerous tasks, I can take that risk.
Anyways, I'm going to try to dig around some more and try to find the
HPET timer API. Theoretically, that should be more accurate then what
I'm seeing with gtod(). I saw Steve's MPDelayUntil() comment, but it
makes no indication what the method is, and it seems unlikely that it
would be any better then this. I'm guessing it's just a wrapper
around nanosleep().
--
Aaron Turner
http://synfin.net/
http://tcpreplay.synfin.net/ - Pcap editing & replay tools for Unix
They that can give up essential liberty to obtain a little temporary
safety deserve neither liberty nor safety. -- Benjamin Franklin
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden