-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Timer precision: Timers are off on windows by 15ms, on Linux by 1.13ms #5021
Comments
I checked what happens with Improvements had been discussed in rust-lang/rust#43376, but nothing was implemented so far. |
Indeed, the 15ms is due to Windows timer resolution. Applications can use On modern Windows a higher resolution timer is also possible using |
Yeah, windows is kinda... a mess as far as timers are concerned. |
This is a major footgun for e.g. Quinn users, since we require higher resolution timers for pacing, otherwise performance suffers drastically. Silently changing global process (system?) state inside Quinn is also unappealing for obvious reasons. I think providing consistent timer resolution would be a better default for tokio (particularly given the use cases tokio has traditionally targeted), and if battery-sensitive uses come up, configuration could be explored. |
Thanks for listing all the alternatives @ChrisDenton ! Apparently windows developers even thought about the battery impact for timebeginperiod
That's neat, but also not useful for the networking use-case. One wouldn't want worse performance in a network stack (which might e.g. do audio streaming, or a download) just because the window is minimized. The Whether it should be the default in tokio and the rust std library? Good question! I'm leaning towards "if a developer started a timer of 1ms, they probably really care that it finishes in the 1-2ms time range. But if the timer is set for 60s they probably won't mind it being 100ms off". So opting in for a higher precision based on the estimated accuracy might work. But I assume tokio creates a timer just once for the runtime and then reuses it - so the decision would happen before the usage is known. |
Is there any fix on the way for this issue? Any alternatives or suggestions for high-resolution/accurate async timers would be appreciated. |
There are two limiting factors to how accurate your timer is:
On windows, the bottleneck is the first factor. The standard OS timer only has a resolution of 15 ms or so. On Linux, the bottleneck is the second factor. The data structure that Tokio uses to store timers only has a resolution of 1 ms. If the Tokio timer does not meet your needs, then I would try the following crates and see if any of them work for you:
|
Tokio could easily work around this, however. The current inconsistent behavior across platforms is surprising. |
I don't really know anything about the situation on Windows. How do you configure it? |
There were detailed discussions of a solution just above in this thread: #5021 (comment), #5021 (comment) |
Version
v1.21.1 (master)
Platform
Windows 11
Description
When setting up a tokio timer with a timeout of 1ms on windows, the timer is late by an averge of 15ms.
One other interesting part is that the windows current thread runtime seems to perform even worse - every timer seems late by 14ms (min and max lateness are all 14-16ms). In the multi-threaded runtime some timers seem to have expired after 7ms.
Linux precision is much better. The timer is late on average by 1.13 ms. However I think it would still be expected to be in the 500us range, if the tokio timer wheel has a granularity of 1ms, and some timers get rounded up and others get rounded down.
Repro (placed into
time_rt.rs
integration test):Windows results
Multi-threaded runtime
Current-thread runtime
Linux results
Current-thread runtime
Multi-threaded runtime
The text was updated successfully, but these errors were encountered: