mach_absolute_time on the iPhone
As programmers on OS X are well aware, the units of mach_absolute_time() have been nanoseconds since 10.2, although this was only documented since 10.5. As the iPhone runs a slimmed down version of OS X, I thought it reasonable that the units would remain the same on the device.
Not so.
On the iPhone, the timebase is different. The mach_timebase_info structure contains a numerator and denominator that can be used to convert between the result returned by mach_absolute_time() and nanoseconds. On OS X Leopard, the numerator and denominator are both 1, meaning that the units are already in nanoseconds. On OS X iPhone, the numerator is 1,000,000,000, while the denominator is 6,000,000. Thus, every unit of absolute time on the iPhone is 166.67 nanoseconds.
So if you’re trying to get some timing from the iPhone using mach_absolute_time() and seeing times that indicate faster results on the iPhone, (not that this happened to me…), make sure to account for the difference in timebase.
Here’s the code for conversion between the iPhone’s mach_absolute_time() and nanoseconds:
/* Get the timebase info */ mach_timebase_info_data_t info; mach_timebase_info(&info); uint64_t start = mach_absolute_time(); /* Do some code */ uint64_t duration = mach_absolute_time() - start; /* Convert to nanoseconds */ duration *= info.numer; duration /= info.denom; /* Log the time */ NSLog(@"My amazing code took %lld nanoseconds!", duration);
Thanks for the information.
Comment by Jesse Towner — October 11, 2008 @ 5:51 pm
Thanks! No telling how many hours you just saved me.
Comment by Nathan — October 18, 2008 @ 9:41 pm
I believe you should always use the values in mach_timebase_info, because they could be different from system to system depending on the host CPU and bus, even just on Mac OS X.
Comment by Justin — February 28, 2009 @ 6:03 am
A good suggestion. While the values are documented to be 1:1 on Mac OS X on all systems up until now, and this will likely continue into the future, code that needs more portability may benefit from using mach_timebase_info as you suggest.
Comment by Devin Lane — March 26, 2009 @ 7:39 pm
Great information! Thanks!
And don’t forget to:
#include
Comment by Julia — April 12, 2009 @ 2:19 am
mach/mach_time.h
Comment by Julia — April 12, 2009 @ 2:20 am
I just checked on my G4 PowerBook running 10.5 – its exactly 30 nanoseconds per tick. So its never been guaranteed to be 1:1.
Win32 has a similar function “QueryPerformanceFrequency()”. Even different Intel/AMD systems have different frequencies, depending on BIOS settings of the various motherboard manufactures. More information here:
http://msdn.microsoft.com/en-us/library/bb173458.aspx
So unless your code is guaranteed to be only running on your own personal mac, please use mach_timebase_info() – that’s what its for :-)
Comment by Justin — April 19, 2009 @ 6:59 am