2016-11-29 9 views
2

Я использую приведенный ниже код для использования mach_wait_until() для ожидания определенного периода времени (в наносекундах).Почему mach_wait_until при запуске на симуляторе?

private func startTimerAndResume(){ 

    let idealNanos: UInt64 = 1250130250 //1.25 seconds 

    let deadline = CFAbsoluteTime(mach_absolute_time() + (timeUnitsFor(nanos: idealNanos))/100) 

    let x = mach_absolute_time() 

    mach_wait_until(UInt64(deadline)) 

    let y = mach_absolute_time() 


    var timeBaseInfo = mach_timebase_info_data_t() 
    mach_timebase_info(&timeBaseInfo) 
    let elapsedNanos = (y - x) * UInt64(timeBaseInfo.numer)/UInt64(timeBaseInfo.denom); 

    print("deadline (aka mach-abs-time + timeUnitsFor()) = \(deadline)") 
    print("(mach-abs-y)-(mach-abs-x) = \(y-x)") 
    print("error in time units = \((y-x)-(timeUnitsFor(nanos: idealNanos))/100)") 
    print("elapsed nanos actual = ", elapsedNanos) 
    print("elapsed nanos ideal = ", idealNanos) 
    print("error in nanoseconds = \(elapsedNanos - idealNanos)") 
} 


private func timeUnitsFor(nanos: UInt64)-> UInt64{ 

    var timeBaseInfo = mach_timebase_info_data_t() 
    mach_timebase_info(&timeBaseInfo) 

    let numer: UInt64 = UInt64(timeBaseInfo.numer) 
    let denom: UInt64 = UInt64(timeBaseInfo.denom) 

    //elapsed time in nanoseconds = timUnits * (numer/denom) ... therefore -> 
    let timeUnits: UInt64 = (nanos*denom/numer)*(UInt64(100))//multiply by 100 to preserve decimal before truncation caused by UInt64() conversion 
    print("timeUnits = \((timeUnits)/100) for target nanos \(nanos) when numer = \(numer) and denom = \(denom)") 
    return timeUnits 
} 

Когда я запускаю это на моем реальном устройстве iPhone ошибка обычно составляет около 1 milisecond и выход заключается в следующем:

timeUnits = 30003126 for target nanos 1250130250 when numer = 125 and denom = 3

deadline (aka mach-abs-time + timeUnitsFor()) = 4025277628801.0

(mach-abs-y)-(mach-abs-x) = 30027213

timeUnits = 30003126 for target nanos 1250130250 when numer = 125 and denom = 3

error in time units = 24087

elapsed nanos actual = 1251133875

elapsed nanos ideal = 1250130250

error in nanoseconds = 1003625

Однако, когда я бегу это на моем тренажере таймер последовательно 70 до 74 миллисекунд поздно, вот выход:

timeUnits = 1250130250 for target nanos 1250130250 when numer = 1 and denom = 1

deadline (aka mach-abs-time + timeUnitsFor()) = 691695760744956.0

(mach-abs-y)-(mach-abs-x) = 1322288698

timeUnits = 1250130250 for target nanos 1250130250 when numer = 1 and denom = 1

error in time units = 72158448

elapsed nanos actual = 1322288698

elapsed nanos ideal = 1250130250

error in nanoseconds = 72158448

Я хотел бы знать, почему симулятор составляет от 70 до 74 миллисекунд с каждым разом. Я делаю переход между наносекундами и единицами времени мага? Thanks

+1

Его симулятор зависит от ОЗУ и использования процессора от Mac. Вы никогда не сможете сравнить симулятор и скорость реального устройства. – Poles

+0

Я не пытаюсь сравнивать скорость, я стараюсь, чтобы симулятор выполнял «mach_wait_until» очень точно. Разве это невозможно? Является ли mach_wait_until неточным при запуске на симуляторе? Почему это так последовательно? всегда 70-74 миллисекунды поздно? – MikeG

ответ

1

Симулятор не является точной эмблемой стрелка с тактовой частотой, предназначенной для точного тестирования часов. Это сборка iOS для Intel и совместное использование ядра с остальной частью ОС хоста.

Возможно, ваши таймеры объединяются в симулятор, тогда как они не на устройстве. В зависимости от конфигурации вашего хоста и версии исполнения процессы симулятора могут выполняться на уровне уровня обслуживания QoS.

Итак, причина, что вы видите разницу в сроках из-за одного или несколько из этих причин:

  • Intel против ARM
  • разных версий ядра (ядро хозяина против парной версии ядра IOS)
  • раздор с другими процессами в вашей системе
  • Таймер коалесценции из-за различных QoS ярусами

Вы не должны полагаться на получение контроля в определенном окне, поскольку это не входит в контракт API. Через какое-то время вы будете назначены по истечении этого времени.

+0

спасибо, что имеет смысл – MikeG

+0

все еще, хотя очень странно, что ошибка такая последовательная, 70-74 миллисекунды каждый раз. Даже когда я настраиваю таймер на ожидание другого периода времени, он остается последовательным ... знаете ли вы какую-либо причину этого? – MikeG

 Смежные вопросы

  • Нет связанных вопросов^_^