-
Notifications
You must be signed in to change notification settings - Fork 194
Decrease idle cpu/power usage #351
Comments
Longer wait intervals may reduce responsiveness. |
Here's the file if anyone wants to investigate. nzbget/daemon/queue/QueueCoordinator.cpp Line 231 in 62b3d47
|
So we would only reduce responsiveness (so start of a download) whenever nothing is downloading? In any case, upping this to 500ms shouldn't be too hard of an impact. |
What does nzbget need to monitor when nothing is downloading? Web requests can block on the socket, queues might wait for fnotify. Hopefully nothing needs to be polled all the time. |
I found the same problem today (high CPU usage) when trying to optimize my power usage. I agree with @vdboor and most loops could be changed to event based instead of polling. Is there any interest in this to happen? I'd try to do this myself in my spare time and submit the patches if so. |
I don't think the 0.3% is high. If there is a simple way to improve this I'm for it but if the change requires a considerable rework of the program I don't think it's worth it. Generally when doing performance optimisations it's important to identify bottlenecks first. Actually it was just a wild guess that the CPU usage is caused by loops, in particular by the loop mentioned in the first post. If you have high CPU usage you can increase wait intervals in the loops, compile the program with different wait intervals and do the measurements. And the most important: any change must preserve compatibility with currently supported operation systems (Linux, Windows, Mac, BSD, Android) and may not add dependencies (other libraries). |
Well, it's not really about performance optimization but about power usage optimization when idle. And for me it's the same are the original reporter said, nzbget is the process using the most CPU when idle. A quick debug shows that even when idle there are 7 threads waking up very frequently and doing nothing. Maybe a first approach could be to suspends those threads when idle? |
@hugbug the problem isn't the % of CPU usage. It's the frequency of wake-ups that no longer allow the CPU to throttle down to low-power mode. Every few seconds, nzbget reminds the CPU that it shouldn't sleep, thus adding to more power consumption (and battery usage) of an otherwise idle machine. |
Thanks to @fedux for reworking thread/mutex primitives and for CPU usage improvements. I've measured CPU usage in idle mode on macOS.
As you can see the main issue here is the article cache manager which wakes up every 5 ms. The second thing is the queue coordinator which wakes up every 100 ms. @fedux: I have an idea for a quick win here: in cache manager count the number of non productive wake ups in a row and increase sleep time after several seconds: from default 5 ms to 100 ms and even to 1000 ms after a few minutes. And a similar approach in queue coordinator. Would you like to try this (or other approaches) or should I? |
I have other commits as work-in-progress here https://github.com/fedux/nzbget/commits/idle and my test instance has ~10 wake-ups per second, but it still needs some work. Still, if you want to try this other idea it would be nice to test a different approach. |
UrlCoordinator is now completely paused (waits without wake ups) when there are no work for it.
Now sleeping much longer, up to next scheduled work, instead of often wake ups to check if the work needs to be performed. This improves CPU usage in idle.
In idle sleeps for 0.5 sec. Wake up immediately when a new item is added to queue. Waking up from paused queue can take longer (up to 0.5 sec).
from Unit “Options.cpp”. The latter now contains only program options (which cannot be changed without reload).
to replace direct calls to “usleep”, with parameter in milliseconds instead of microseconds.
If there are no active downloads the disk service can now sleep for 10 seconds instead of 1.
Up to 2 second when queue is empty or downloads are paused.
With further changes the number of wake ups in idle has been reduced to as low as 1-2 per second or even less. MacOS and Linux report 0.0% CPU usage now. All numbers refer to nzbget running in daemon mode. CPU usage is higher if nzbget is running with console output (started with |
This reduces CPU usage, especially in idle.
When idling nzbget seems to still use quite a bit of cpu. Looking at powertop it is by far the most consuming process on my machine.
powertop:
Usage Events/s Category Description
1.8 ms/s 212.3 Process /usr/bin/nzbget -c /etc/nzbget/nzbget.conf -D
top shows around 0.3% cpu usage:
top:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND
5451 nzbget 20 0 823788 13184 4880 S 0.3 0.3 0:10.04 nzbget
strace shows only sleep nanosleep system calls every 100 milliseconds:
strace:
restart_syscall(<... resuming interrupted nanosleep ...>) = 0
nanosleep({0, 100000000}, NULL) = 0
nanosleep({0, 100000000}, NULL) = 0
nanosleep({0, 100000000}, NULL) = 0
Maybe increasing the hardcoded timeout from 100 m.s. to 1 second will help?
The text was updated successfully, but these errors were encountered: