2016-11-29 66 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毫秒。我在做納秒和馬赫時間單位之間的轉換是錯誤的嗎?謝謝

+1

它因爲模擬器取決於Mac的RAM和CPU使用情況。你永遠無法比較模擬器和真實設備的速度。 – Poles

+0

我不想比較速度,我試圖讓模擬器非常精確地執行'mach_wait_until'。這不可能嗎? mach_wait_until在模擬器上運行時是否不精確?爲什麼它如此一致呢?總是遲到70-74毫秒? – MikeG

回答

1

模擬器不是一個時鐘週期準確的手臂模擬器,用於時鐘週期準確測試。它是英特爾的iOS版本,與主機操作系統的其餘部分共享內核。

您的計時器可能在模擬器中合併,而他們不在設備上。根據您的主機配置和運行時版本,模擬器進程可能會在實用程序QoS層運行。

所以,你看到的定時的差的原因是因爲一個或一個以上的這些原因的:

  • 英特爾VS ARM
  • 不同的內核版本(主機內核VS配對的iOS內核版本)
  • 爭與您的系統上,由於不同的QoS等工序
  • 定時器凝聚層

您不應該依賴於在特定窗口內獲取控制權,因爲這不在API合同中。您將在該時間過後的某個時間點安排。

+0

非常感謝 – MikeG

+0

雖然很奇怪,錯誤是如此一致,每次70-74毫秒。即使當我調整計時器以等待不同的時間段時,它仍然是一致的......你知道有什麼理由嗎? – MikeG

相關問題