mach_absolute_time()产生不稳定的时序

时间:2012-10-08 05:11:30

标签: ios

我正在尝试在iOS上优化一个函数(FFT),并且我已经设置了一个测试程序来计算它在几百个调用上的执行时间。我在函数调用之前和之后使用mach_absolute_time()来计时。我在运行iOS 6的第4代iPod touch上进行测试。

大多数计时结果大致相互一致,但偶尔一次运行将比其他运行时间长得多(多达100倍)。

我很确定这与我的实际功能无关。每次运行具有相同的输入数据,并且是纯粹的数值计算(即,没有系统调用或存储器分配)。如果我用一个空的for循环替换FFT,我也可以重现这个。

有没有人注意到这样的事情?

我目前的猜测是,我的应用程序的线程以某种方式被操作系统中断。如果是这样,有什么办法可以防止这种情况发生吗? (这不是将在App Store上发布的应用程序,因此非公共API可以用于此。)

我不再拥有iOS 5.x设备,但我确信在iOS 6更新之前没有发生这种情况。

编辑: 这是一种更简单的再现方式:

for (int i = 0; i < 1000; ++i)
{                                         
    uint64_t start = mach_absolute_time();
    for (int j = 0; j < 1000000; ++j);   
    uint64_t stop = mach_absolute_time(); 
    printf("%llu\n", stop-start);         
}                                         

在调试中编译它(因此for循环没有被优化掉)并运行;大多数值大约是220000,但偶尔会有10倍或更大的值。

3 个答案:

答案 0 :(得分:1)

mach_absolute_time()实际上是非常低级且可靠的。它在所有iOS设备上以稳定的24MHz运行,从3GS到iPad第四代。这也是获取时序信息的最快方法,取决于CPU,需要0.5μs到2μs。但如果你被另一个线程打断了,你当然会得到虚假的结果。

具有最高优先级的SCHED_FIFO将允许您占用CPU,但最多只能持续几秒钟,然后操作系统会判断您太贪心了。您可能希望在运行计时测试之前尝试睡眠(5),因为这会产生一些“信用”。

您实际上不需要启动新线程,您可以暂时更改当前线程的优先级:

struct sched_param sched;
sched.sched_priority = 62;
pthread_setschedparam( pthread_self(), SCHED_FIFO, &sched );

请注意sched_get_priority_min&amp;最大回报保守15&amp;但是,这仅对应于约0.25至0.75的绝对优先级。实际可用范围是0到62,对应于0.0到1.0。

答案 1 :(得分:0)

根据我的经验,mach_absolute_time不可靠。现在我使用CFAbsoluteTime代替。它以秒为单位返回当前时间,精度比第二时间好得多。

const CFAbsoluteTime newTime = CFAbsoluteTimeGetCurrent();

答案 2 :(得分:0)

当app在其他线程中花费一些时间时会发生这种情况。