在我们的应用程序中,我们必须以高分辨率对其进行采样。
我已经看到目标c中的常规NSTimer
,不能超过50毫秒。
我们需要以至少约1毫秒的速率进行采样。
这很奇怪,当iphone处理器超过1ghz时,1ms内无法采样!
我有两个想法:1。做一个while(1)
可能会给我时钟,或者,使用加速度计样本(他那么快吗?),我相信两者都不行。
对这个简单问题的任何想法?
答案 0 :(得分:0)
实现该分辨率的精确计时器真的不是一件简单的事。要获得高度精确的计时器,您可能需要实现自己的运行循环。如果它只需要单个定时器,现在动态定时器插入/删除,那么它的实现相当简单。
正如你所说,运行while(...)循环并在那里你需要睡一段时间。这是最棘手的部分,因为有时以前的实际经过时间可能比实际时间更长/更小,所以你必须补偿它。
while( running ) {
gettimeofday(&t_start, NULL);
{
double sleep_time = cur_timer->_M->nextFireTime() - elapsedTime;
if( sleep_time > 0 ) {
Thread::sleep(sleep_time); //sleep time is in seconds
}
}
gettimeofday(&t_end, NULL);
elapsedTime += Utils::timeval_diff(t_end, t_start);
if( running ) {
gettimeofday(&t_start, NULL);
{
//perform all timer callbacks here
}
gettimeofday(&t_end, NULL);
}
elapsedTime += Utils::timeval_diff(t_end, t_start);
}
这是我自己的runloop实现的非常简化版本。这里的主要想法是你必须跟踪实际的经过时间并补偿任何时间溢出。
以下是1ms时间步的示例输出:
period: 0.001000 (0.001000) elapsed: 0.001160 (0.001160)
period: 0.001000 (0.002000) elapsed: 0.000988 (0.002148)
period: 0.001000 (0.003000) elapsed: 0.000982 (0.003130)
period: 0.001000 (0.004000) elapsed: 0.001003 (0.004133)
period: 0.001000 (0.005000) elapsed: 0.001004 (0.005137)
.....
period: 0.001000 (4.280872) elapsed: 0.001022 (4.299592)
period: 0.001000 (4.281872) elapsed: 0.002627 (4.302219)
period: 0.001000 (4.282872) elapsed: 0.000018 (4.302237)
period: 0.001000 (4.283872) elapsed: 0.000266 (4.302503)
period: 0.001000 (4.284872) elapsed: 0.001091 (4.303594)
period: 0.001000 (4.285872) elapsed: 0.001026 (4.304620)
要获得更精确的结果,请在具有高优先级的单独线程上运行计时器。