使用MacOS / iOS,有时会给我们一些基于主机时钟的计时信息。 (在我的情况下,它是CoreMidi,具有Midi输入的timeStamp。)
我需要计算两次之间的“准确”经过时间,但是减去那些基于时钟的主机时间并不十分准确,尤其是在比较较长的时间差(例如60分钟)时。 为了查看这些主机时差的准确性,我编写了测试代码。 结果使我经过的时间差超过1毫秒,这是不可接受的。 我想到了CFAbsoluteTimeGetCurrent(),gettimeofday()和clock_gettime()函数延迟的可能性。更改实验时间30秒,60秒...经过的时间差成比例增加。 是否有任何API可以将基于时钟的经过时间转换为实际经过时间 时间?我以为客户知道自己的精度,因此可以转换... 如果不是,最好的解决方法是什么? 您可能建议每次我需要时都调用CFAbsoluteTimeGetCurrent()(及其他),但是1)像MIDI这样的用例,很多输入会在短时间内出现。 2)如果回调函数给出了主机的基本时间,则在调用回调函数不太准确之后,它已经被延迟到花费时间。 谢谢你。
mach_timebase_info_data_t machTimebaseInfo;
if (KERN_SUCCESS == mach_timebase_info(&machTimebaseInfo) ) {
NSLog(@"OK");
}
UInt64 m1 = mach_absolute_time() * machTimebaseInfo.numer / machTimebaseInfo.denom;
//gettimeofday
static struct timeval now_time;
gettimeofday(&now_time, NULL);
UInt64 t1 = ((UInt64)now_time.tv_sec * 1000000) + (UInt64)now_time.tv_usec;
// clock_gettime
// static struct timespec startTime;
// clock_gettime(CLOCK_REALTIME, &startTime);
// UInt64 t1 = (startTime.tv_nsec + (startTime.tv_sec * NSEC_PER_SEC)) / NSEC_PER_USEC;
__block CFAbsoluteTime cft1 = CFAbsoluteTimeGetCurrent();
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60 * NSEC_PER_SEC));
dispatch_after(time, dispatch_get_main_queue(), ^{
gettimeofday(&now_time, NULL);
UInt64 t2 = ((UInt64)now_time.tv_sec * 1000000) + (UInt64)now_time.tv_usec;
// static struct timespec startTime;
// clock_gettime(CLOCK_REALTIME, &startTime);
// UInt64 t2 = (startTime.tv_nsec + (startTime.tv_sec * NSEC_PER_SEC)) / NSEC_PER_USEC;
CFAbsoluteTime cft2 = CFAbsoluteTimeGetCurrent();
UInt64 m2 = mach_absolute_time() * machTimebaseInfo.numer / machTimebaseInfo.denom;
UInt64 mach_diff = (m2 - m1) / 1000;
UInt64 time_diff = t2 - t1;
// UInt64 time_diff = (cft2 * USEC_PER_SEC) - (cft1 * USEC_PER_SEC);
NSLog(@"time elapsed: %llu", time_diff);
NSLog(@"mach elapsed: %llu", mach_diff);
if( time_diff > mach_diff ) {
NSLog(@"dif : %llu", (time_diff - mach_diff));
} else {
NSLog(@"dif : -%llu", (mach_diff - time_diff));
}
});