使用mach_absolute_time在iphone上的帧速率

时间:2010-06-20 03:32:18

标签: iphone ipad opengl-es frame-rate

我有以下代码,并希望得到其他一组眼睛以确保我已经编写了正确的代码来计算场景的帧速率。你能请进来吗?

这是使用SDK 3.2为iPad编写的。

谢谢!

- (void)drawView:(id)sender
{
 mach_timebase_info_data_t timer;

 mach_timebase_info(&timer);
 uint64_t t1 = mach_absolute_time();

    [renderer render];

 uint64_t delta = mach_absolute_time() - t1;
 delta *= timer.numer;
 delta /= timer.denom;

 NSLog(@"%lld ms: %.2f FPS", delta, 1000000000.0f/delta);
}

3 个答案:

答案 0 :(得分:1)

如果您想测量渲染OpenGL所花费的时间,这将无效。 OpenGL操作是并行处理的,不会影响CPU的时序。您可以分析发出OpenGL调用所需的时间,但您将无法看到完成它们需要多长时间。

这很不幸,但这很有意义。这可能就是为什么每个人都只是在考虑他们的帧率:如果GPU无法及时完成处理,你的CPU就会被阻止,而你的计时器(很可能是CADisplayLink)也不会“及时”发射。

您可能需要查看(昂贵的)分析工具,例如gDEBugger,但我不确定它们是否适用于iOS。

答案 1 :(得分:0)

我使用CFAbsoluteTime来计算openGL应用程序中的帧持续时间。我停止使用mach_time,因为结果不可靠。

- (void)update {

    // Compute Frame Duration
    static CFAbsoluteTime sPreviousTime = 0;
    const CFAbsoluteTime newTime = CFAbsoluteTimeGetCurrent();
    const CFAbsoluteTime deltaTime = newTime - sPreviousTime;
    sPreviousTime = newTime;
    float frameDuration = deltaTime;
    // keep frameDuration in [0.01 ; 0.5] seconds
    if (frameDuration > 0.5f) {
        frameDuration = 0.5f;
    } else if (frameDuration < 0.01f) {
        frameDuration = 0.01f;
    }

    [self tick:frameDuration]; // use frameDuration to do something every frame

}

答案 2 :(得分:0)

简短回答:是的,你所做的是正确的。

更长的答案:要获得两次mach_absolute_time呼叫之间的增量的时间(以秒为单位),您需要执行以下操作:

// I do this once at launch.
mach_timebase_info_data_t timer;
mach_timebase_info( &timer );

// Start time.
uint64_t t1 = mach_absolute_time( );

// Do activity.

// End time.
uint64_t t2 = mach_absolute_time( );

// Calculate delta.
uint64_t delta = t2 - t1;

// Use denom/numer from timer.
delta *= timer.numer;
delta /= timer.denom;

// Convert nanoseconds to seconds.
float secondsElapsed = ( float )( delta / 1000000000.0 );

当然,如果你想要一个FPS,你需要秒的倒数:

1.0f / secondsElapsed;

在您的情况下,而不是:

float secondsElapsed = ( float )( delta / 1000000000.0 );

你在做:

float inverseSecondsElapsed = ( float )( 1000000000.0 / delta );

所以你确实按照预期获得了FPS,所以所有这些都应该按预期工作。