site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; bh=aL0dw/QhgXGmCzpPen1Gur6MnQbPBUwfUkvA4Y8un1E=; b=iJo7pSkdeR1VpA1J4avIM0HUJMeD8FEnoyvk8DP8FSWh1KlJXs7BJdsjbc+BfaRYEfuUEN0Ds1x68dlt5KL4oiSh6LQwfhJcxbaGTk5+Lu4WoF9G4hf1UBNAwaldoCNwjEdllFAXI30PgOtox8z1ShCY/2xk6JPkk0QiTMsBa+o= Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=P0OLpK2u25fFqrJxQ/1fFUBeb4+ycUrs1ZHo/y4QyIQ7y0FyVcp65vGJ1sk/Z94PNCYiRmf2Sfa6ibQEl97uwByxJA1d79L0VC84OB0j/DRh4zsGWH7AnVS4KEgdLUv8k4qGsjesAWeFOugJkmi+gmA1Me0haZ2k+/KjhAOYhMc= On Wed, Mar 26, 2008 at 5:34 AM, Andrew Gallatin <gallatin@cs.duke.edu> 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 (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... This email sent to site_archiver@lists.apple.com