4 ms·
> Not my experience at all. Granted I haven't tried writing a loop like this in 20ish years, because once you spot that mistake you don't tend to make it again,
by diath 2y ago
> Not my experience at all. Granted I haven't tried writing a loop like this in 20ish years, because once you spot that mistake you don't tend to make it again, and CPUs are better now.
You can trivially verify it by running the following, I have personally been using "sleep for 1ms in a loop to prevent CPU burn" for years and never noticed it having any impact, it's not until I go into microseconds when I can start noticing my CPU doing more busy work.
// g++ -std=c++20 -osleep sleep.cpp
#include <thread>
#include <chrono>
int main(int, char **)
{
while (true) {
std::this_thread::sleep_for(std::chrono::milliseconds {1});
}
return 0;
}
> Another thing to note is when you call sleep with a low value it may decide not to sleep at all, so this loop just might be constantly doing syscalls in a tight loop.
On what system? AFAIK, if your sleep time is low enough, it will round up to whatever is the OS clock resolution multiple, not skip the sleep call completely. On Linux, it will use nanosleep(2) and I cannot see any mention of the sleep not suspending the thread at all with low values.
- asveikau 2y agoIf memory serves, Windows treats a sleep under the scheduler quantum length as a yield. It may take you off the cpu if there's something else to run but it may not. Meanwhile burning up cycles may prevent low power states. At any rate, back to the code at hand, there are many ways to block on SIGINT without polling. But it's also hugely odd that this code does not read events from the X11 socket while it does so. This is code smell, and a poorly behaved X client.
- orbisvicis 2y agoI thought that Linux behaved the same, but I'm not finding any proof in `man 2 nanosleep`...
- eqvinox 2y agoYou can't find that proof because Linux does the opposite. Unless your task is SCHED_REALTIME, all timers have a little bit of slack at the end that allows the kernel to group wakeup events. You can configure this (for non-RT tasks) with prctl(PR_SET_TIMERSLACK). https://lxr.linux.no/#linux+v6.7.1/kernel/time/hrtimer.c#L2094 https://lxr.linux.no/#linux+v6.7.1/kernel/time/hrtimer.c#L20... https://www.man7.org/linux/man-pages/man2/PR_SET_TIMERSLACK.2const.html https://www.man7.org/linux/man-pages/man2/PR_SET_TIMERSLACK....
- orbisvicis 2y agoSorry! I was looking for documentation that on Linux sleep(0) yields.
- eqvinox 2y agoThere is no code in nanosleep that converts it into a yield, and in fact a nanosleep(0) is a nanosleep(50µs) with the default timer slack value. If you want to yield, call sched_yield() …
- orbisvicis 2y agoI looked into this a bit further and it seems to be a range from [0,50]. [1] explains that if there is a pre-existing timer interrupt at 0, then the queue will be resumed at 0. But yes - given no other timers it will resume at 50. 1. https://people.kernel.org/joelfernandes/on-workings-of-hrtimers-slack-time-functionality https://people.kernel.org/joelfernandes/on-workings-of-hrtim...
- gpderetta 2y agoIt used to be the case that glibc implemented nanosleep for small values below the scheduling quantum with a spin loop. It was explicitly documented to do so. This was changed sometimes in the last 20 years, probably with battery powered devices becoming more prevalent and CPUs implementing more advanced sleep states.
- 01HNNWZ0MV43FF 2y ago> never noticed I'd love to see numbers with a Kill-A-watt between the PC and the wall
- winrid 2y agoWhy? Running an empty loop a thousand times a second is literally almost nothing to any cpu released in the past 20yrs at least
- EasyMark 2y agoRunning an empty loop with no sleep or other yield type operation will peg one of your cores if you pin it to that core. Int main() { while(1) {} } compile that with -O0 and see what happens.
- 01HNNWZ0MV43FF 2y agoFor science, literal proving hypotheses science
- winrid 2y agoWell, I already run my setup through a kilowatt. I don't see a difference with Python, which you can argue should be 10-100x less efficient: import time while True: time.sleep(0.001) also the script itself it bounces between 0% and 1% cpu usage