8 ms·
Windows Timer Resolution: The Great Rule Change
- jfreuden 6y agoFrom a technical point of view, this is an interesting change, and I'm not sure if it's a bug or not. From a scientific point of view, I definitely bristled at "cleaned up to remove randomness"... :P
- londons_explore 6y agoThis seems deliberate... It's trying to prevent one application 'randomly breaking' when another application is running. Seems like a good move to me - just a bit of a shame a few applications might break.
- stinos 6y agoIt shouldn’t be doing this, but it is In my opinion this still remains the conclusion, as it has been for the past decades. I cannot remember when I read a bit on Sleep() behavior and timeBeginPeriod() but I remember that what I read was enough to make clear you just shouldn't rely on these (unless you're 100% sure the consequences are within your spec and will remain so), also not because the workarounds are also widely known (IIRC - things like using WaitForSingleObject if you need accurate Sleep).
- vardump 6y ago> things like using WaitForSingleObject if you need accurate Sleep You won't get any more timing accuracy with WFSO.
- stinos 6y agoYeah I see now other comments mention this as well; any idea if this has been changed then, or was the info I seem to recall having read wrong? (and is there another way to achieve it?)
- stinos 6y agoToo late to edit my other reply, but note that according to sibling comment from jlokier elsewhere, you will.
- duke360 6y agoi've always tought that Sleep(n) means Sleep at least n... not Sleep around, or Sleep exactly n, what i'm missing here?
- wtallis 6y ago"Sleep at least n" is too broad of a spec to be useful. It basically guarantees that users of that function will come to expect or rely on behavior that is not covered by that spec, such as expecting that their program will be woken up again in a relatively short period of time rather than next week, or that the program will actually sleep for a non-trivial amount of wall time instead of immediately waking back up. Microsoft deserves at least some of the blame when application programmers come to rely on behavior that isn't officially part of the spec, and Microsoft definitely deserves some of the blame when they change that behavior without even doing those programmers the courtesy of documenting the change. "Windows 10" is too much of a moving target, and it's about time Microsoft stopped trying to pretend to the public that it's all one operating system. If they're not going to usefully document potentially breaking changes, they should at least do us all the courtesy of bundling these changes up into a release that increments the major version number, and gives us the option of not upgrading for a few years instead of having the software as a service model forced upon us. (Given what I've written above, it probably won't surprise you to find out I recently spent a decent chunk of time trying to find a workaround for a different undocumented change brought by Windows 10 version 2004).
- mehrdadn 6y ago> a different undocumented change brought by Windows 10 version 2004 Any chance you could share this so those of us who haven't dealt with it yet might have a heads-up?
- rwallace 6y ago> One case where timer-based scheduling is needed is when implementing a web browser. The JavaScript standard has a function called setTimeout which asks the browser to call a JavaScript function some number of milliseconds later. Chromium uses timers (mostly WaitForSingleObject with timeouts rather than Sleep) to implement this and other functionality. This often requires raising the timer interrupt frequency. Why does it require that? Timeouts should normally be on the order of minutes. Why does Chrome need timer interrupts to happen many times per second?
- Sniffnoy 6y agoThis isn't the browser's network timeouts, this is the JavaScript function setTimeout() which can be used in scripts and which, as mentioned, takes an argument in milliseconds. Chrome needs to be able to support whatever setTimeout() call a website might make, and those are rarely going to be minutes long; setTimeout() is just used for "call this function after a specified amount of time". The fact that the word "timeout" is used in the name does not mean that it has any relation to network timeouts!
- wolf550e 6y agoJavaCcript setTimeout is used for animations.
- sdflhasjd 6y agoThis is exactly why requestAnimationFrame is a thing though.
- cm2187 6y agoDoes the timer behave in the same way on Windows Server?
- vardump 6y agoNo, but some timing related aspects are different on multi CPU socket systems. Like it might be much (even 1000x) slower to read QueryPerformanceCounter due to cross-CPU synchronization issues.
- gambiting 6y agoAh yes, reminds me how on my previous project I was in charge of writing a server to mix audio for multiple clients in real time. The server worked well on my local Windows 10 machine, but when deployed to a cloud instance of Windows Server 2016 it ran very very poorly, just barely quickly enough to process data in time. That's when I discovered that doing a "process more data if there is any, if not - sleep(1)" loop is a very bad way of doing it, as on Windows Server 2016 "sleep(1)" means "sleep 16ms". It all worked fine once the timer resolution was changed to 1ms, but yeah, the default value will screw you over if you have anything this time sensitive and are using sleeps or waits on windows.
- mehrdadn 6y agoI don't even get why you would Sleep() in such a scenario. If you want to fire every 1ms, wouldn't you use an actual timer? Like one of SetTimer/SetThreadpoolTimer/CreateTimerQueueTimer/timeSetEvent/CreateWaitableTimer maybe? Why would you rely on Sleep() for periodicity?
- gambiting 6y agoLiterally all of those methods will only wake up at the system's timer interval at the earliest - if that happens to be 16ms, there is nothing you can do to sleep/wait less than 16ms. Even WaitForObject calls can only wait for the minimum equal to the system's timer resolution.
- mehrdadn 6y agoThe resolution or behavior of other APIs is beside my point. I'm saying, even if in an ideal world Sleep did wait exactly how much you told it to, I don't get why you would feel justified in using it to trigger something every N ms. Even if N = 16ms. Your code itself might takes 3ms to run one time, 6ms another time, or 9ms a third time. Sleeping 16ms every time just won't get you periodic behavior even if Sleep is perfectly accurate. Right? i.e. Sleep() just seems like the wrong API regardless of everything else...
- badsectoracula 6y agoAbout the game fixing utilities, while it is annoying that these wont work at the moment, they should still be able to work by installing a hook that attaches itself to the game's process and calls timeBeginPeriod (several other unofficial game patches work like this already).
- BitterAmethyst 6y agoAt work we have an application that calls `timeBeginPeriod(1)` to get timer callbacks (from `CreateTimerQueue`) firing at 5ms resolutions but we are not seeing the behaviour described in the article. We observe no change to the timer resolution after calling `timeBeginPeriod(1)`, which unfortunatly is a breaking change to our app. The lack of information and response from Microsoft on this has been quite frustrating.
- vardump 6y agoYeah, I just came to the same conclusion. Win10 2004 timer changes are breaking. Timer frequency adjustments (timeBeginPeriod) don't seem to affect Windows timers in the same process like they used to do! Again. In Win10 2004, if you do timeBeginPeriod(1), timers in the same process (other than using the deprecated multimedia timer) seem to only trigger every 15-16 ms or so instead of 1 ms. This is bad. As a sidenote about Win10 2004, after timeBeginPeriod(1), Sleep(1) seems to take about 2 ms per call. Or at least it seems to take about 1950 ms to call Sleep(1) 1000 times when I tested it. Confusing.
- BitterAmethyst 6y agoYeah. There is an a ticket opened in the `Feedback Hub` app for it that I've been checking but there seems to be no acknowledgement from Microsoft about this, which is one of the more annoying aspects.
- perryizgr8 6y agoI don't know if something is wrong with my internet or machine, but a lot of graphs/pictures seem to be missing on this page.
- JoeAltmaier 6y ago<rant> Our models of computer timers are woefully inadequate. These things execute billions of instructions per second. Why shouldn't we be able to schedule a timer at sub-millisecond resolution? Answer: we can. But the APIs are very old and assume conditions no longer present. Or something like that. Anyway, they don't get the job done. Everybody seems to start a hardware timer at some regular period, then simulate 'timer interrupts' for applications off that timer's interrupt. If you want 12.5ms but the ol' ticker is ticking at 1ms intervals, you get 13 or so depending on where in an interval you asked, it could be 12. Even if nobody is using the timer, its ticking away wasting CPU time. So the tendency is, to make the period as long as possible without pissing everybody off. Even back in the 1980's, I worked on an OS running on the 8086 with a service called PIT (Programmable Interval Timer). You said what interval you wanted; it programmed the hardware timer for that. If it was already running, and your interval was shorter than what remained, it would reprogram it for your short time, then when it went off it reprogrammed it for the remainder. It kept a whole chain of scheduled expirations sorted by time. When the interrupt occurred it'd call the callback of the 1st entry and discard it. Then it'd reprogram the timer for the remaining time on the next. It took into account the time of the callback; the time to take the interrupt and reprogram. And it achieved sub-millisecond scheduling even back on that old sad hardware. And when nobody was using the timer, it didn't run! Zero wasted CPU. Imagine how precise timers could be today, on our super duper gigahertz hardware. But what do we get? We get broken, laggy, high-latency, late timer callbacks at some abominable minimum period. Sigh. </rant>
- LoSboccacc 6y ago> Why shouldn't we be able to schedule a timer at sub-millisecond resolution it's not just the API, the whole operating system need to be aware of the need to operate at such frequency, because even if the clocks are faster, the software gets interrupted all the time. what good would a nanosecond api do if an interrupt can stall the cpu for a microsecond? hence the need for a whole class of realtime operating systems. the next question would then be, why aren't all computers using a realtime operating system? because with the relaxed time constraints we get great returns in speed and cost.
- _0ffh 6y ago
- trashface 6y agoI tested my own system using Bruce's "measure_interval.cpp" program (on Windows 1909): - Slack (sometimes) sets the global timer to 1ms when it is in the foreground, but restores it in background - Spotify sets the global timer to 1ms, no matter what. Even if it isn't playing. - Skype sets 1ms, if started at Startup (which it defaults to), even though I am logged out and it just has a tray icon. But when I manually start it, it doesn't (always) set it to 1ms. - VSCode will set it to 1ms when you are interacting with it, but will eventually revert to 15.6ms if left alone (even if it is still in foreground). - Firefox doesn't appear to set it (on its own; I presume that if I opened a tab that was using a low setTimeout or requestAnimFrame it might). Spotify is interesting. A lot of people probably have that app, and since it sets 1ms unconditionally, it would have been setting fast-timer mode prior to the 2004 update, which could inadvertently "speed up" whatever games people were running. That includes my own game, which uses a foreground sleep of as low as 1ms to try to hit its time target, and I don't call timeBeginPeriod. I guess I'll find out when I get the 2004 update.
- ampdepolymerase 6y agoHalf the apps here are Chromium based though.
- dstaley 6y agoI once spent ages trying to determine why a Python unit test that sorted timestamps constantly failed on Windows. In the test, we compared the timestamps of performed operations, and checked to confirm that the operations happened in sequence based on their timestamp (I'm sure many of you see where this is going). On Windows, the timestamp for all the actions was exactly the same, so when sorted, the actions appeared out-of-order. It was then that I discovered Python's time library on Windows only reports times with a resolution of ~1ms, whereas on Linux the same code reports times with a resolution of ~10us. That one was actually super fun to track down, but super disappointing to discover it's not something that's easily remedied. (For those about to suggest how it should have been done, the application also stored an atomic revision counter, so the unit test was switched to that instead of a timestamp.)
- CodesInChaos 6y agoOn Windows 8 or later you can use GetSystemTimePreciseAsFileTime to get higher precision timestamps. https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime https://docs.microsoft.com/en-us/windows/win32/api/sysinfoap...
- TonyTrapp 6y ago> A program might depend on a fast timer resolution and fail to request it. There have been multiple claims that some games have this problem (...) Yup, I wrote such a (small, freeware) game 15+ years ago. I wasn't aware of timeBeginPeriod at the time, but I observed that for some inexplicable reason, the game ran more smoothly when Winamp was running in the background. :-)
- the8472 6y ago> and the timer interrupt is a global resource. Shouldn't this at least be per-core rather than global? Then most cores can keep scheduling at a low tick rate and only one or two have to take care of the jittery processes.
- throwaway889900 6y agoSeems like this was reported over 4 months ago! [1] [1] https://developercommunity.visualstudio.com/content/problem/1093078/timebeginperiod-function-dont-change-anymore-the-r.html https://developercommunity.visualstudio.com/content/problem/...
- deleted 6y ago[deleted]
- Stierlitz 6y agoThat's an interesting read. I recall reading about some airline communication system that used to freeze when a 32 bit counter in Windows overflowed. Would the way windows implements timer interrupts have anything to do with this.
- garaetjjte 6y agoAuthor might want to disable Wordpress "pingback" feature, as it seems abused. WTF is that, it seems bots are copying content, swapping random words and reposting on some generic looking sites..? What's even the purpose of this?