今天在 iOS 下找类似 Windows 平台的 GetTickCount 这样的函数,找到一个叫 mach_absolute_time() 的函数,但是Apple的文档非常不
给力,找个半天才比较清楚是怎么回事,原来这个函数返回的值只是启动后系统CPU/Bus的clock一个tick数,跟GetTickCount不同,
因为这个 GetTickCount 是系统启动后的毫秒数,所以要获得系统启动后的时间需要进行一次转换,还好Apple给出了一个官方的方法
Technical Q&A QA1398
Mach Absolute Time Units
https://developer.apple.com/library/mac/#qa/qa1398/_index.html
另外我找到一些关于这个函数的说明文档如下:
http://www.macresearch.org/tutorial_performance_and_time
mach_absolute_time is a CPU/Bus dependent function that returns a value based on the number of "ticks" since the system started up.
uint64_t mach_absolute_time(void);
Declared In: <mach/mach_time.h>
Dependency: com.apple.kernel.mach
This function returns a Mach absolute time value for the current wall clock time in units of uint64_t.
https://developer.apple.com/library/mac/#documentation/Performance/Conceptual/LaunchTime/Articles/MeasuringLaunch.html
mach_absolute_time reads the CPU time base register and is the basis for other time measurement functions.
还有一个似乎是实现代码:
http://opensource.apple.com/source/Libc/Libc-186/mach.subproj/mach_absolute_time.c
#include<stdint.h>
#include<mach/clock.h>
extern mach_port_t clock_port;
uint64_t mach_absolute_time(void)
{
#ifdefined(__ppc__)
__asm__ volatile("0: mftbu r3");
__asm__ volatile("mftb r4");
__asm__ volatile("mftbu r0");
__asm__ volatile("cmpw r0,r3");
__asm__ volatile("bne- 0b");
#else
mach_timespec_t now;
(void)clock_get_time(clock_port, &now);
return (uint64_t)now.tv_sec * NSEC_PER_SEC + now.tv_nsec;
#endif
}
+ (uint64_t)GetPIDTimeInNanoseconds
{
uint64_t start;
uint64_t end;
uint64_t elapsed = 0;
Nanoseconds elapsedNano;
for(int i = 0; i < 1000; i++)
{
// Start the clock.
start = mach_absolute_time();
// Call getpid. This will produce inaccurate results because
// we're only making a single system call. For more accurate
// results you should call getpid multiple times and average
// the results.
(void) getpid();
// Stop the clock.
end = mach_absolute_time();
// Calculate the duration.
elapsed += (end - start);
}
elapsed = elapsed / 1000;
// Convert to nanoseconds.
// Have to do some pointer fun because AbsoluteToNanoseconds
// works in terms of UnsignedWide, which is a structure rather
// than a proper 64-bit integer.
elapsedNano = AbsoluteToNanoseconds( *(AbsoluteTime *) &elapsed );
return * (uint64_t *) &elapsedNano;
}