【问题标题】:frame rate on the iphone using mach_absolute_timeiphone 上使用 mach_absolute_time 的帧速率
【发布时间】:2010-06-20 03:32:17
【问题描述】:

我有以下代码,并希望得到其他人的关注,以确保我编写了正确的代码来计算场景的帧速率。你能插话吗?

这是使用 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);
}

【问题讨论】:

  • 我个人可能只是使用 CFAbsoluteTime 并完成它。这样您就不必将周期转换为秒。
  • CACurrentMediaTime() 更适合这个。
  • 我不知道这些功能。所以你的意思是它们更好,因为我不必将它乘以 10^9 或做任何分子或分母?

标签: iphone ipad opengl-es frame-rate


【解决方案1】:

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

这是不幸的,但它是有道理的。这可能是每个人都只关注帧率的原因:如果 GPU 无法及时完成处理,您的 CPU 就会被阻塞,并且您的计时器(很可能是 CADisplayLink)不会“及时”触发。

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

【讨论】:

  • 您可以调用 glFinish() 来强制 GPU 完成挂起的操作。对于小型操作,结果可能不可靠,但对于完整的帧,它可以帮助估计 GPU 开销。
【解决方案2】:

我使用 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

}

【讨论】:

    【解决方案3】:

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

    更长的答案:要获得两次 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,所以一切都应该按预期工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 2010-11-29
      • 1970-01-01
      • 2018-10-25
      • 2010-12-17
      • 2021-06-29
      相关资源
      最近更新 更多