3

In our render-loop we've always had a FPS limiter in the form of this_thread::sleep_until(Thisframe + milliseconds(1000 / 60)); but after compiling on the latest version the FPS never went above 32. So played around with the delay and found that any sleep >= 1 micro-second added 5-16ms. Anyone else noticed something similar?

// std::this_thread::sleep_for(std::chrono::nanoseconds(N));
------------------------------------------------------------
N           |  Max (ns)  | Avg (ns)  | Min (ns)
------------------------------------------------------------
1           541          532          530
10          526          526          523
100         526          526          525
1'000       5'105'253    5'035'142    4'945'181
10'000      15'849'245   15'829'724   15'751'297
100'000     15'900'155   15'884'466   15'846'923
1'000'000   15'885'041   15'877'936   15'872'767
10'000'000  15'899'457   15'884'640   15'881'723
// std::this_thread::sleep_for(std::chrono::nanoseconds(N));
------------------------------------------------------------
N           |  Avg (ns)
------------------------------------------------------------
3'000       17'759'597
2'500       13'888'173
2'000       10'093'005
1'500       9'393'417 
1'000       4'735'949
750         2'841'692
700         5'445'165
650         4'658'634
600         2'153
500         1'789
Convery
  • 183
  • 7
  • 2
    `this_thread::sleep_until` is [build out of `_Thrd_sleep`](https://github.com/microsoft/STL/blob/9bb2a983dfd8da3305f0b6f2c7a278a5ddc43823/stl/inc/thread#L183) which is in turn [built out of `Sleep()`](https://github.com/microsoft/STL/blob/c385d02702554841bdf1b83afe6a4a16f0df0ca9/stl/src/cthread.cpp#L76) and `Sleep` does not guarantee an exact sleep, only that it will sleep *at least* as long as specified. In general, you cannot count on resolution higher than the system clock tick, which is around 10-15ms. – Raymond Chen Jan 22 '21 at 20:29
  • Then it's very strange that it did work well in the previous versions. Not to mention that the the performance hit seems to only occur after 600ns and ramp up with the sleep length, peaking at ~3us. – Convery Jan 22 '21 at 21:44
  • 3
    You might be seeing this: [New Thread.Sleep behaviour under Windows 10 October Update 20H2](https://stackoverflow.com/questions/64633336/new-thread-sleep-behaviour-under-windows-10-october-update-20h2). The system used to let you get away with somebody else cranking the timer resolution via `timeBeginPeriod()` (usually the web browser), but now it requires you to do it yourself. – Raymond Chen Jan 23 '21 at 00:15
  • That was indeed the issue, thank you Raymond. MSDN still says that `timeBeginPeriod()` is global so expected the behaviour to be the same as always =P – Convery Jan 23 '21 at 13:19

1 Answers1

3

Solved thanks to @Raymond Chen's comment on the question above:

You might be seeing this: New Thread.Sleep behaviour under Windows 10 October Update 20H2. The system used to let you get away with somebody else cranking the timer resolution via timeBeginPeriod() (usually the web browser), but now it requires you to do it yourself.

mskfisher
  • 3,291
  • 4
  • 35
  • 48
Convery
  • 183
  • 7