Pshenichny (pshenichny) wrote,
Pshenichny
pshenichny

Измерение точности таймера iPhone [Objective C]

Цель и задачи: Измерение точности работы таймера iPhone. Измерение влияния iOS на скорость работы приложения.
Материалы: iPhone SDK 4.0, XCode 3.2.3, iPod Touch 3G, iOS 3.1.3


Самый точный таймер на iPhone: mach_absolute_time().
По виду выглядит очень похоже на QueryPerformanceCounter из Windows, тоже возвращает время в попугаях. Чтобы привести показания к человеческому времени, есть функция mach_timebase_info().

Делаем простую вещь: вызываем 10 раз подряд mach_absolute_time(), считаем сколько прошло времени между вызовами и смотрим на разброс значений. Таким образом определяем точность таймера.

Второе: 10 раз крутим длинный цикл, внутри которого делаем простые вещи (например, постоянно увеличиваем переменную) и считаем сколько времени занимает этот длинный цикл. Если разброс времени сильно больше точности таймера - то это время кто-то у нас украл. Ясно кто - многозадачная операционная система.

Перед всеми замерами подождем 5 секунд, чтобы минимизировать влияние операционной системы (которая после запуска приложения делает анимацию раскрытия окна).

Замеры делаем минимум четыре раза. Сборка Release.

На симуляторе (Core2Duo 2.66Ghz) такие цифры: узнать показания таймера = 27..30 наносекунд, точность таймера = 3 наносекунды (миллиард наносекунд = 1 секунде, свет за 1 наносекунду пройдет всего 30 см).
MacOS ворует от 0,05 до 0,33 % времени вне зависимости от длинны цикла.

Но, симулятор это не интересно, пробуем на iPod Touch 3G (предварительно выключив и включив его).
Узнать показания таймера: 1208..1416 наносекунды.
Средняя точность таймера: 125 наносекунды, худшая 209 наносекунд.
Влияние iOS: от 0,5 и аж до 12 %, в среднем 1 %.

Ни разные стройки компилятора, ни запуск сразу с устройства - не оказал существенного влияния на точность таймера.


#import <mach/mach_time.h>

#define LOOP_COUNT 10000000

mach_timebase_info_data_t info;

void PrintResult ( uint64_t * time );


int main () 
{
    mach_timebase_info ( & info );

    // подождем 5 секунд
    const uint64_t start = mach_absolute_time ();
    while ( (mach_absolute_time () - start) * info.numer / info.denom < 5000000000 )
    {}

	
    uint64_t time_loop [10];
    uint64_t time [10];
	
    // посчитаем время десяти длинных циклов
    time_loop [0] = mach_absolute_time ();

    for ( int i = 1; i < 10; ++i )
    {

        for ( volatile int j = 0; j < LOOP_COUNT; ++j )
        {}

        time_loop [i] = mach_absolute_time ();
    }

    // посчитаем время mach_absolute_time
    time [0] = mach_absolute_time ();

    time [1] = mach_absolute_time ();
    time [2] = mach_absolute_time ();

    time [3] = mach_absolute_time ();
    time [4] = mach_absolute_time ();

    time [5] = mach_absolute_time ();
    time [6] = mach_absolute_time ();

    time [7] = mach_absolute_time ();
    time [8] = mach_absolute_time ();

    time [9] = mach_absolute_time ();

    // результаты
    NSLog ( @"long loop:" );

    PrintResult ( time_loop );

    NSLog ( @"mach_absolute_time:" );

    PrintResult ( time );
    return 0;
}


void PrintResult ( uint64_t * time )
{
    uint64_t min = UINT64_MAX, max = 0, avg = 0;

	
    for ( int i = 0; i < 9; ++i )
    {

        const uint64_t dt = (time [i+1] - time [i]) * info.numer / info.denom;

        NSLog ( @"delta %i: %lld nanoseconds", i, dt );
        if ( dt > max )

            max = dt;
        if ( dt < min )

            min = dt;
        avg += dt;
    }
    avg /= 9;

    NSLog ( @"max = %lld, min = %lld, average = %lld, max delta = %lld, %% delta = %f", max, min, avg, max - min, 100.0f * (max-min) / avg );
}


Еще по теме:
Измерение точности таймера для iPhone и Web [Unity]

Порекомендовать:
Tags: article, ios, objective c, timer, xcode
Subscribe
  • Post a new comment

    Error

    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 4 comments