【问题标题】:Why is mach_wait_until late when run on simulator?为什么在模拟器上运行时 mach_wait_until 迟到?
【发布时间】:2016-11-29 05:08:30
【问题描述】:

我正在使用下面的代码来使用 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 毫秒左右,输出如下:

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 毫秒。我在纳秒和马赫时间单位之间的转换是否错误?谢谢

【问题讨论】:

  • 这是因为模拟器取决于 Mac 的 RAM 和 CPU 使用率。你永远无法比较模拟器和真实设备的速度。
  • 我不是要比较速度,我是想让模拟器非常精确地执行mach_wait_until。这不可能吗? mach_wait_until 在模拟器上运行时是否不精确?那为什么会如此一致呢?总是迟到 70-74 毫秒?

标签: ios swift ios-simulator mach


【解决方案1】:

模拟器不是用于时钟周期精确测试的时钟周期精确手臂仿真器。它是为 Intel 构建的 iOS 版本,并与主机操作系统的其余部分共享内核。

您的计时器可能会在模拟器中合并,而它们不在设备上。根据您的主机配置和运行时版本,模拟器进程可能在实用程序 QoS 层运行。

因此,您看到时间差异的原因是以下一个或多个原因:

  • 英特尔与 ARM
  • 不同的内核版本(主机内核与配对的 iOS 内核版本)
  • 与系统上的其他进程争用
  • 由于不同的 QoS 层而导致的计时器合并

您不应该依赖在特定窗口内重新获得控制权,因为这不在 API 合同中。您将被安排在该时间过后的某个时间点。

【讨论】:

  • 虽然很奇怪,错误如此一致,每次70-74毫秒。即使我调整计时器以等待不同的时间段,它仍然保持一致......你知道这是什么原因吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-01
  • 1970-01-01
  • 2014-10-01
  • 2017-03-27
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多