13th May, 2013, 01:07 AM
A few weeks ago I was asked to make little guide on CPU/IO priorities handling. I'm not an expert in the field so if you find something overly complex or incorrect (I will surely try to avoid the last) please tell me!
The idea behind this is fairly simple, have downloads running on background and whenever you must use xbmc make sure that it get's most of the kernel scheduler attention. I manage to do that by simply altering the process CPU and I/O(Input/Output) priority.
Introduction
The utilities Nice and Ionice manage the priority of a given process and its hard drive(I/O) priorities respectively.
Nice
CPU priorities are handled according to a number which defaults to 0 and whose values range from -20(Maximum priority) to 19(Minimum priority), a few system specific processes default to high priorities. You can see all of this using the top utility:
I'm also running sabnzbd,sickbeard,transmission and couchpotato each with its own user, so you will notice yours different.
The column that indicates the nice value is the one called NI. Notice that I give my downloads a low priority (10) than default (0) and Xbmc a higher one (-5).
Ionice
Harddrive access priority is divided in 3 scheduling classes:
-Realtime: Highest priority and subdivided in 8 priority levels with 0 being the highest one. Should be used with care as it can easily make your raspberry pi unresponsive.
-Best-effort:This is the default class, it's also subdivided in 8 levels same as Realtime. The priority level is dynamically adjusted according to the CPU priority (nice level) by the following formula: io_priority = (cpu_nice + 20) / 5.
-Idle: A process under this class only gets disk time when no other higher priority process is using it.
Changing startup priority
Now, this is how I have set it all up.
All download related processes have its priority set up at 10 so that they have a lower priority than default. Thanks to it, whenever I run another processes on my Raspberry Pi it gets more CPU, for example if I wish to run apt-get update the downloads would throttle down until it finishes.
The other way around for Xbmc, I have its priority set up at -5 so that it always has a little higher priority and it doesn't stutter if someone is using Xbmc while I'm running commands on the background.
If you want to keep it simple, you could just make Xbmc have a higher priority and leave the downloads at the default one, depending on your case that could prove enough, to do it you must change this file:
Change this bit:
Adding the option -N -5 to the start-stop-daemon:
That would change xbmc nice level to -5, and its ionice best-effort value to io_priority = (cpu_nice + 20) / 5=3, higher than the default value of 4.
To test that it works, restart the service:
and check with the top utility that its nice level has changed to -5.
If you want to also change its ionice level manually, just add this:
That would also set best-effort scheduler with priority 2.
If that doesn't prove enough, lower downloads priority, you should do the same change for each process init script (sabnzbd, couchpotato, sickbeard, transmission...) note that only transmission and sabnzbd are I/O intensive, the other ones rely only on CPU.
Well, that's it! if somebody knows an easier way just tell it! This is the easiest I found, although I have done it different, all my download related processes are under the same group and I have set that groups default priority to 10 (modifying /etc/security/limits.conf) but it's a little bit more complicated and the only real advantage is that I can easily change all the priorities.
Here are a couple of links with more information regarding nice and ionice utilities.
http://www.nixtutor.com/linux/changing-priority-on-linux-processes/
http://man.he.net/man8/start-stop-daemon
http://linux.die.net/man/1/ionice
Sorry if I misspelled something, english is not my native language.
The idea behind this is fairly simple, have downloads running on background and whenever you must use xbmc make sure that it get's most of the kernel scheduler attention. I manage to do that by simply altering the process CPU and I/O(Input/Output) priority.
Introduction
The utilities Nice and Ionice manage the priority of a given process and its hard drive(I/O) priorities respectively.
Nice
CPU priorities are handled according to a number which defaults to 0 and whose values range from -20(Maximum priority) to 19(Minimum priority), a few system specific processes default to high priorities. You can see all of this using the top utility:
Terminal
xbian@Raspberry ~ $ top
top - 20:31:25 up 7 min, 1 user, load average: 1.21, 2.45, 1.37
Tasks: 90 total, 1 running, 89 sleeping, 0 stopped, 0 zombie
%Cpu(s): 21.4 us, 6.8 sy, 5.2 ni, 66.3 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
KiB Mem: 382820 total, 319176 used, 63644 free, 32092 buffers
KiB Swap: 127996 total, 0 used, 127996 free, 124272 cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2483 xbian 20 -5 310m 45m 15m S 26.0 12.3 1:59.86 xbmc.bin
2856 xbian 20 0 6284 1464 1052 R 1.3 0.4 0:00.66 top
2213 sabnzbd 30 10 178m 11m 1864 S 1.0 3.2 0:04.03 SABnzbd.py
29 root 1 -19 0 0 0 S 0.7 0.0 0:01.85 VCHIQ-0
42 root 20 0 0 0 0 S 0.3 0.0 0:09.95 mmcqd/0
2195 couchpot 30 10 114m 42m 5004 S 0.3 11.4 2:51.66 python
2383 sickbear 30 10 191m 25m 3496 S 0.3 6.9 0:17.63 python
2458 transmis 30 10 33496 3360 2440 S 0.3 0.9 0:02.01 transmission-da
top - 20:31:25 up 7 min, 1 user, load average: 1.21, 2.45, 1.37
Tasks: 90 total, 1 running, 89 sleeping, 0 stopped, 0 zombie
%Cpu(s): 21.4 us, 6.8 sy, 5.2 ni, 66.3 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
KiB Mem: 382820 total, 319176 used, 63644 free, 32092 buffers
KiB Swap: 127996 total, 0 used, 127996 free, 124272 cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2483 xbian 20 -5 310m 45m 15m S 26.0 12.3 1:59.86 xbmc.bin
2856 xbian 20 0 6284 1464 1052 R 1.3 0.4 0:00.66 top
2213 sabnzbd 30 10 178m 11m 1864 S 1.0 3.2 0:04.03 SABnzbd.py
29 root 1 -19 0 0 0 S 0.7 0.0 0:01.85 VCHIQ-0
42 root 20 0 0 0 0 S 0.3 0.0 0:09.95 mmcqd/0
2195 couchpot 30 10 114m 42m 5004 S 0.3 11.4 2:51.66 python
2383 sickbear 30 10 191m 25m 3496 S 0.3 6.9 0:17.63 python
2458 transmis 30 10 33496 3360 2440 S 0.3 0.9 0:02.01 transmission-da
The column that indicates the nice value is the one called NI. Notice that I give my downloads a low priority (10) than default (0) and Xbmc a higher one (-5).
Ionice
Harddrive access priority is divided in 3 scheduling classes:
-Realtime: Highest priority and subdivided in 8 priority levels with 0 being the highest one. Should be used with care as it can easily make your raspberry pi unresponsive.
-Best-effort:This is the default class, it's also subdivided in 8 levels same as Realtime. The priority level is dynamically adjusted according to the CPU priority (nice level) by the following formula: io_priority = (cpu_nice + 20) / 5.
-Idle: A process under this class only gets disk time when no other higher priority process is using it.
Changing startup priority
Now, this is how I have set it all up.
All download related processes have its priority set up at 10 so that they have a lower priority than default. Thanks to it, whenever I run another processes on my Raspberry Pi it gets more CPU, for example if I wish to run apt-get update the downloads would throttle down until it finishes.
The other way around for Xbmc, I have its priority set up at -5 so that it always has a little higher priority and it doesn't stutter if someone is using Xbmc while I'm running commands on the background.
If you want to keep it simple, you could just make Xbmc have a higher priority and leave the downloads at the default one, depending on your case that could prove enough, to do it you must change this file:
Terminal
xbian@Raspberry ~ $ sudo nano /etc/init.d/xbmc
PHP Code:
do_start()
{
if [ $(ps -A | grep xbmc.bin | wc -l) -eq 0 ]; then
start-stop-daemon -c xbian -u xbian --start --quiet --pidfile $
echo $(start-stop-daemon -c xbian -u xbian -m --start --$
fi
}
PHP Code:
do_start()
{
if [ $(ps -A | grep xbmc.bin | wc -l) -eq 0 ]; then
start-stop-daemon -c xbian -u xbian --start --quiet --pidfile $
echo $(start-stop-daemon -N -5 -c xbian -u xbian -m --start --$
fi
}
To test that it works, restart the service:
Terminal
xbian@Raspberry ~ $ sudo service xbmc restart
If you want to also change its ionice level manually, just add this:
PHP Code:
do_start()
{
if [ $(ps -A | grep xbmc.bin | wc -l) -eq 0 ]; then
start-stop-daemon -c xbian -u xbian --start --quiet --pidfile $
echo $(start-stop-daemon -N -5 -I best-effort:2 -c xbian -u xbian -m --start --$
fi
}
If that doesn't prove enough, lower downloads priority, you should do the same change for each process init script (sabnzbd, couchpotato, sickbeard, transmission...) note that only transmission and sabnzbd are I/O intensive, the other ones rely only on CPU.
Well, that's it! if somebody knows an easier way just tell it! This is the easiest I found, although I have done it different, all my download related processes are under the same group and I have set that groups default priority to 10 (modifying /etc/security/limits.conf) but it's a little bit more complicated and the only real advantage is that I can easily change all the priorities.
Here are a couple of links with more information regarding nice and ionice utilities.
http://www.nixtutor.com/linux/changing-priority-on-linux-processes/
http://man.he.net/man8/start-stop-daemon
http://linux.die.net/man/1/ionice
Sorry if I misspelled something, english is not my native language.