Standard C++ thread sleep timers exceed expected time on ARM based Mac Mini

When executing timing benchmarks on macOs we see a much more variable sleep time relative to Linux on arm64 or Linux on x86_64 . If we have a timing loop firing every 16ms, we frequently see timings of 20+ms. We have turned off timer coalescing using

sudo /usr/sbin/sysctl -w kern.timer.coalescing_enabled=0

But we are still seeing lots of spikes in expected period as compared to Linux. Is there anything we can further do to stabilize the timing of our macOs host and improve timer performance? Are there any settings we can alter (similar to the one above) to get more accurate timing performance?

Example:

  1. These are sleeps that are used with standard C++ functions like
std::this_thread::sleep_until()
  1. This is measured by having a loop printing the current system time and sleeping as above
  for (int i = 0; i < ITERATIONS; i++) {

    printf("%llu\n", current_time_ns());

    std::this_thread::sleep_until(std::chrono::steady_clock::now() + std::chrono::milliseconds(16))

}

The same code was compiled for

arm64 macOS

arm64 Linux

x86_x64 Linux

And was found to be far more variable in the macOS arm64 case.

There are lots of things you can do here. As to what you should do, that depends on the context.

macOS is capable of hitting relatively tight real-time goals, but the way you do that very much depends on the context. If you run a simple test tool from Terminal, the system is going to assume that you’re not particularly latency sensitive.

So, what’s the big picture here? Beyond the benchmark, what are you actually trying to achieve with low-latency timers?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Jumping in here to add some context as I work with krackajack:

The overall aim is to generate a 16ms timing interval for the purposes of emulating hardware and the call will ultimately be made from macOS specific code from within an emulator (qemu).

We found the behaviour of the timers to be the same from within the emulator as in a native process (i.e. the behaviour doesn't seem to be affected by the emulator).

Standard C++ thread sleep timers exceed expected time on ARM based Mac Mini
 
 
Q