2

我正在尝试优化 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 倍或更多。

4

3 回答 3

1

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

具有最高优先级的 SCHED_FIFO 将允许您占用 CPU,但最多只能占用几秒钟,然后操作系统会认为您太贪婪了。您可能想在运行计时测试之前尝试 sleep( 5 ),因为这会建立一些“信用”。

您实际上不需要启动一个新线程,您可以使用以下方法临时更改当前线程的优先级:

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

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

于 2013-02-28T00:41:31.410 回答
1

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

const CFAbsoluteTime newTime = CFAbsoluteTimeGetCurrent();
于 2012-12-13T16:13:06.767 回答
1

当应用程序在另一个线程中花费一些时间时会发生这种情况。

于 2014-07-13T02:00:24.980 回答