4

Thread.Sleep used to be tied to the system clock which clocked in at a interval at roughly 16 ms, so anything below 16ms would yield 16ms sleep. The behaviour seems to have changed some way down the line line.

What has changed? Is Thread.Sleep no longer tied to the system clock but to the high res timer? Or has the default system clock frequency increased in Windows 10?

edit: It seems people are intersted in knowing why I use Thread.Sleep, its actually out of the scope of the question, the question is why the behavior have changed. But anyway, I noticed the change in my open source project freepie https://andersmalmgren.github.io/FreePIE/

Its a input/output emulator which is controlled by the end user using Iron python. That runs in the background. It has no natural interrupts. So I need to marshal the scripting thread so it does not starve an entire core.

Anders
  • 17,306
  • 10
  • 76
  • 144
  • 1
    What indications do you have for that? what version of .net framework are you using? Edit: i had never any indication that apart from Sleep(1) and Sleep(0) anything between 16 and 1 is not propperly executed. That would have one of my projects pritty useless. Maybe your BIOS HPET option has changed? – Venson Dec 31 '19 at 12:53
  • I tried both full and core same thing. I'm on latest windows 10, AMD 3950x on a Asus Crosshair 6 Hero. Havent changed anything related to system clock. – Anders Dec 31 '19 at 12:59
  • Why the question? For starters, applications could always change the system-wide interval. That's what Chrome does, leading to battery drain as the system keeps waking a lot more often than it should – Panagiotis Kanavos Dec 31 '19 at 13:00
  • Why the question? Its a unknown side effect. I want to know why. I have a opensource program called freepie. It used to run at a frequency of 16ms now it runs at 1. As long as the scripts you run in it is not hardcoded to 16ms (which they shouldnt) it doesnt matter. But I would like to know what have chagned since in my world 16ms is the rate it shuld run at – Anders Dec 31 '19 at 13:02
  • There's no *reason* for this to change though. If you want fast timing, or high FPS you use the appropriate APIs, not Thread.Sleep. Games don't use Thread.Sleep to control animations and yet, they can work at 100+ FPS. It's not just the GPU - the *CPU* has to tell the GPU what to draw and where, 100 times/sec. Sound applications send bytes to the sound card's DAC a lot faster than that – Panagiotis Kanavos Dec 31 '19 at 13:02
  • My program is a generic i/o mapper. I need a default framerate that is not tied to I/O etc – Anders Dec 31 '19 at 13:03
  • 1
    @Anders what's changed is that you run Chrome at the same time. You shouldn't depend on Sleep's resolution for timing in any case. – Panagiotis Kanavos Dec 31 '19 at 13:03
  • I did a restart of OS, no change. So its not chrome. – Anders Dec 31 '19 at 13:06
  • If I didnt sleep and the user of my program does not trigger some kind of interupt on the thread the program will eat 100% of that core. Its not desiarable from a background type program – Anders Dec 31 '19 at 13:07
  • Games run as fast as they can, becase they get natural interupts when drawcalling etc. Animations are solved by multiplying everything that is dependent on time with frame deltatime. This is another problem. – Anders Dec 31 '19 at 13:09

2 Answers2

1

Thanks to Hans Passant comment which I first missed I found the problem. It turns out Nvidias driver suit is the problem maker.

Platform Timer Resolution:Outstanding Timer Request A program or service has requested a timer resolution smaller than the platform maximum timer resolution. Requested Period 10000 Requesting Process ID 13396 Requesting Process Path \Device\HarddiskVolume2\Program Files\NVIDIA Corporation\NVIDIA GeForce Experience\NVIDIA Share.exe

This is so idiotic on so many levels. In the long run this is even bad for the environment since any computer with nvidia will use more power.

edit: Hans Comment, relevant part:

Too many programs want to mess with it, on top of the list is a free product of a company that sells a mobile operating system. Run powercfg /energy from an elevated command prompt to find the evildoer, "Platform Timer Resolution" in the generated report.

Anders
  • 17,306
  • 10
  • 76
  • 144
  • It is shovelware, you can easily live without it. Renaming the .exe file is the easiest way to kill it. Do document the powercfg.exe command. – Hans Passant Dec 31 '19 at 13:41
  • I actually use geforce experience to capture content for my Game Studio :D – Anders Dec 31 '19 at 13:44
0

The newer hardware does have a more precise timer, indeed. But the purpose of Thread.Sleep is not to be precise, and it should not be used as a timer.

It is all in the documentation:

If dwMilliseconds is less than the resolution of the system clock, the thread may sleep for less than the specified length of time. If dwMilliseconds is greater than one tick but less than two, the wait can be anywhere between one and two ticks, and so on.

Also very important is that after the time elapses, your thread is not automatically run. In stead, the thread is marked as ready to run. This means that it will get time only when there are no higher priority threads that are also ready to run, and not before the currently running threads consume their quantum or get into a waiting state.

Nick
  • 4,787
  • 2
  • 18
  • 24
  • The real time (high res) timer is more precise. But that shouldn't change the behavior of the system clock? – Anders Dec 31 '19 at 13:19