2012-10-08 47 views
2

我试图在iOS优化功能(进行FFT),我已经建立了一个测试程序,它的计时执行过几百个电话。我在函数调用之前和之后使用mach_absolute_time()来计时。我正在对运行iOS 6的iPod touch第4代进行测试。不稳定时序结果()

大部分计时结果彼此大致一致,但偶尔一次运行需要比其他时间长得多(长达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倍或更多的值。

+0

而不是直接从main()运行我的测试,我现在从一个新的线程运行它们。我使用pthreads创建线程,将策略设置为SCHED_FIFO,并将优先级设置为最大值。这并不能消除这个问题,但平均时间现在已经足够有用了。不过,我很想知道是否有更有效的方法来防止中断。 – sjmerel

回答

0

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

const CFAbsoluteTime newTime = CFAbsoluteTimeGetCurrent(); 
1

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

SCHED_FIFO最大优先将让你养猪的CPU,但只有最多几秒钟,然后OS决定你这个人太贪婪。在运行计时测试之前,您可能想尝试睡眠(5),因为这会产生一些“信用”。

你实际上并不需要开始一个新的线程,可以暂时用这个改变当前线程的优先级:

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

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

0

它发生时,应用程序花费一些时间在另一个线程。