частота кадров на iphone с использованием mach_absolute_time - PullRequest
0 голосов
/ 20 июня 2010

У меня есть следующий код, и я хотел получить другой набор глаз, чтобы убедиться, что я написал правильный код для расчета частоты кадров сцены. Не могли бы вы присоединиться?

Это написано для iPad с использованием SDK 3.2.

спасибо!

- (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 ]

1 голос
/ 26 октября 2010

Если вы хотите измерить время, затраченное на рендеринг OpenGL, это не сработает. Операции OpenGL обрабатываются параллельно и не влияют на синхронизацию ЦП. Вы можете указать время, необходимое для выполнения вызовов OpenGL, но вы не сможете увидеть, сколько времени им потребовалось для их завершения.

Это прискорбно, но имеет смысл. Вероятно, это причина того, что каждый просто смотрит на свою частоту кадров: если графический процессор не может завершить обработку вовремя, ваш процессор блокируется и ваш таймер (скорее всего, CADisplayLink) не будет срабатывать «вовремя».

Возможно, вы захотите взглянуть на (дорогие) инструменты профилирования, такие как gDEBugger, но я не уверен, что они работают на iOS.

0 голосов
/ 19 июля 2014

Краткий ответ: да, то, что вы делаете, правильно.

Более длинный ответ: чтобы получить время в секундах для дельты между двумя вызовами 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, как задумано, поэтому все должно работать, как задумано.

0 голосов
/ 13 декабря 2012

Я использую 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

}
...