Friday, January 19, 2018

RaspBerry Pi - The Audio Engine - Part 4 - Advanced OS Tuning Measures

Nice to have you back @ Part 4 of the series.

By now you already should have a nicely running audio system based on the Raspberry PI3(+), a nice little HAT DAC and piCorePlayer as audio engine.


This part of the "RPI Audio Engine series" will cover some more modifications.



This article is Work-in-Progress!  Latest update: Nov-16-2018



As with all tuning measures my ultimate goal is to make the system more efficient. 

Everything until now, including some basic tweaks (HDMI off/WLAN off etc.), could be accomplished by using the WEB GUI.

Now it's time to switch to commandline.  Some might don't like it. Some might be afraid 
of it. 
Just give it a try. It's like "painting by numbers". Just follow strictly what I'm gonna show you.

Keep in mind. You can't do much wrong. If anything's gone south...  ...just restore your backed-up SD-card, 

I'll try to walk you through the journey. Tweak by Tweak.

Still. Remember. Everything you do you do at your own risk! Just to be clear about that.



Once more. Before your start make a backup of your SD card first. 


Let's get started.


1. ssh login

I won't get into that right now. On Windows you need to install puTTY. On OSX and Linux you can simply use a terminal.There are numerous guides out there how to accomplish ssh access from any platform.

You'll need the IP address. We covered that in Part 2
You'll need a user name. For pCP it's  "tc"
You'll need a password. For pCP it's   "piCore"

Basically you'll end up like this:






From now we better execute all commands as user "root" - the admin user of Linux. This way we avoid that any of the commands we'll execute fails.

Enter:

sudo su

Now you switched to user root. It stays like that as long as you remain in the terminal!

  
Next we mount the boot-partition of the SD-card to be be able to edit some system config files. You can compare that with a BIOS setup on a normal computer. On the PI the BIOS info is kept in mainly two different text-files.

Note: On Raspbian or Arch Linux Arm we wouldn't have to mount the boot partition!

Just type (or copy/paste):

mount /dev/mmcblk0p1 /mnt/mmcblk0p1





Let's backup the files we gonna touch - run this step only once!
 



cp /mnt/mmcblk0p1/config.txt /mnt/mmcblk0p1/config.txt.orig
cp /mnt/mmcblk0p1/cmdline.txt /mnt/mmcblk0p1/cmdline.txt.orig


Now we're set to introduce this or that tweak.


Measure 1  -- Turn Off Power and Act LEDs


There are two LEDs on the PI. These 

a. draw about 5mA current or less - in blinking mode
b. might cause an annoying light spectacle in a dark listening room.
c. and cause certain activity on the CPU

Th eprovess to accomplish this, is different for every RPI model.

For RPI 3B:

1. Disable the ACT LED

echo 'dtparam=act_led_trigger=none' >> /mnt/mmcblk0p1/config.txt 
echo 'dtparam=act_led_activelow=on' >>/mnt/mmcblk0p1/config.txt

2. Disable the PWR LED

echo 'dtparam=pwr_led_trigger=none' >>/mnt/mmcblk0p1/config.txt
echo 'dtparam=pwr_led_activelow=on' >>/mnt/mmcblk0p1/config.txt

FOR RPI 3B+

echo 'dtoverlay=pi3-act-led>>/mnt/mmcblk0p1/config.txt


Disable the ACT LED

echo 'dtparam=act_led_trigger=none>>/mnt/mmcblk0p1/config.txt


Disable the PWR LED

echo 'dtparam=pwr_led_trigger=none>>/mnt/mmcblk0p1/config.txt

echo 'dtparam=pwr_led_activelow=off>>/mnt/mmcblk0p1/config.txt


Disable the ethernet port LEDs

echo 'dtparam=eth_led0=14>>/mnt/mmcblk0p1/config.txt

echo 'dtparam=eth_led1=14>>/mnt/mmcblk0p1/config.txt



Measure 2 -- Isolate Interrupts

Basically all HW interrupts (IRQ) run on CPU0. This is specific to the RPI. 
On a PC IRQs get distributed over several CPUs. On a PC you can even assign IRQs manually to a specific CPU. Not so on the PI.

Now. We do what's possible under these circumstances.

This measure will isolate all running SW processes
from CPU0. 

CPU0 will then handle IRQs exclusive! And SW will run on CPU1-3.
On CPU0 won't be any competition between IRQs and SW processes anymore.

Good news:

Since pCP 4.0 this feature is available through the WEB GUI. You'll find related info in the pCP4.0 article.


EVERYTHING BELOW WILL SOON BE UPDATED!


Measure 3 -- Shutdown Webserver and cron

As usual, ssh login first.

piCorePlayer is a very lean system. Only a very few services/processes are running.
We can still lower the number of services, to increase the system efficiency. 

The Webserver is probably the most demanding service. Once everything is configured
there's pretty much no need to have that server running idle in the background.

Cron is a daemon that allows to run tasks at certain times.

With this measure we're using the service cron to shutdown the webserver after
3 minutes. And while we're at it, cron shuts down itself too.

3 minutes will also give you plenty of time to disable this measure from a browser again.

Now we have to generate a script that will do the job and that's been called by cron.


Copy &  paste below after you've done a reboot and a ssh login again. 

####################################
sudo su
cd /mnt/mmcblk0p2/tce
touch tune.sh
chmod 770 tune.sh
cat <<"EOF" >tune.sh
#!/bin/sh
#
#
###
test -f /tmp/tunep1 || { touch /tmp/tunep1 ; exit 0 ; } ;
pkill busybox-httpd

sleep 1
pkill crond
touch /tmp/tunep2

EOF
sync
reboot

#####################################


Now we can activate a cron job that calls the script that we just generated.
While running the script, it'll also kill the cron daemon! 

We'll do this from the WEB GUI inside the "Tweak" section.






Enter (copy/paste) above shown "Custom Cron Command" and press "Save". 

###############

*/3 * * * * /mnt/mmcblk0p2/tce/tune.sh

###############


3 minutes after a power-up or reboot the WEB-UI should no longer be working.

If you want to disable above measure, just remove the  "Custom Cron Command" string and save it within 3 minutes after boot.



Measure 4 -- Disable DHCP and ssh

Now. This measure builds upon Measure 3, which has to be done before this one! 

This exercise I wouldn't consider optional. Just to mention it.

There are basically just two remaining processes that we are able to spare. 
It's dhcp and ssh.

Obviously if we kill ssh - the remote login daemon - we won't be able to ssh login any more. You may consider to run this measure as the very final exercise. Or you disable
the cron job inside the "Schedule Cron Jobs" menu as described in Measure 3 first. 
And then you go ahead with this one.

Copy &  paste below after you've done a reboot and a ssh login again. 

####################################
sudo su
cd /mnt/mmcblk0p2/tce
cat <<"EOF" >>tune.sh
sleep 1
pkill udhcpc
sleep 1
pkill sshd
sync
echo 3 > /proc/sys/vm/drop_caches

EOF
sync
reboot

####################################

That'll be it.


Measure 5 -- Disable CPU throttling

To save power, all modern CPUs throttle the CPU in low demand situations.
That would happen while streaming at a load of 2%.  
Since the throttling process is quite intrusive - lurking and acting in the background all the time - we can just disable it. 
We can control the clock frequencies ourselves. We'll actually lower them in Measure 6.

There are two side effects I'm aware of:

1. Temperature will rise a little.
2. If Overclocking AND overvolting (over_voltage>0) AND force_turbo=1 is set,
    the RPI warranty bit gets set and that means you'll loose warranty for your RPI.
    Read this reference !  

    Disclaimer: As usual: It's your risk to run this exercise!


With this measure, we're just setting the force_turbo parameter.

Copy &  paste below after you've done a reboot and a ssh login again. 

###################################################
sudo su
grep -qs '/mnt/mmcblk0p1' /proc/mounts || {
   sudo mount /dev/mmcblk0p1 /mnt/mmcblk0p1
}
cd /mnt/mmcblk0p1
cat <<"EOF" >>config.txt
### Turn off CPU throttling 
force_turbo=1

EOF
sync
reboot

###################################################


Measure 6 -- Underclocking


What we can do now is "underclocking" the PI3. We don't need the 1200MHz 
default clock. Obviously that'll be causing quite some more power consumption and heat.
We don't want the 600MHz lower limit, which might be a little low. We also don't need high clock rates on the GPU side.

I ended up with a combination of clock rates that can all be divided by 200. It's been just a thought to avoid a mixup of several even and uneven frequencies. 

Copy &  paste below after you've done a reboot and a ssh login again. 


###################################################
sudo su
grep -qs '/mnt/mmcblk0p1' /proc/mounts || {
   sudo mount /dev/mmcblk0p1 /mnt/mmcblk0p1
}
cd /mnt/mmcblk0p1
cat <<"EOF" >>config.txt
### Introduce underclocking  of CPU, GPU and RAM
arm_freq=800
gpu_freq=200
core_freq=200
sdram_freq=400

EOF
sync
reboot

###################################################

Measure 7 -- Overclocking the SD-card

If you're using a rather new and highest quality SD-Card you might want to introduce
some overclocking. Since piCorePlayer mainly accesses the SD-card during boot and shutdown this measure won't show much of an impact. 
The clockrate being used will be 100MHz. It'll be smaller then the core-clock
by an even factor of two. 

I'm running 16G Sandisk Ultra HC 1 Class 10 ( sells usually @ 9.99 over here)

WARNING: 
Certain SD-cards might get corrupted or even damaged. It's 100% your risk if you run this exercise. If not sure leave this task alone. Don't blame me if you end up with a bricked SD -card!


###################################################
sudo su
grep -qs '/mnt/mmcblk0p1' /proc/mounts || {
   sudo mount /dev/mmcblk0p1 /mnt/mmcblk0p1
}
cd /mnt/mmcblk0p1
cat <<"EOF" >>config.txt
### Introduce overclocking  of SD-card
dtoverlay=sdhost,overclock_50=100

EOF

sed -i '/^\s*$/d' config.txt
sync
reboot

###################################################


Measure 8 -- Network parameters

The default parameter used for the network interface can be tweaked a little. 
You might want to try this too.
We just add the required commands to the tune.sh script we're using already 
for killing processes in Measure 3+4.

Copy &  paste below after you've done a reboot and a ssh login again. 

####################################
sudo su
cd /mnt/mmcblk0p2/tce
cat <<"EOF" >>tune.sh
sleep 1
sysctl -w net.core.rmem_max=26214400
sysctl -w net.core.wmem_max=26214400
sysctl -w net.ipv4.tcp_rmem='4096 1048576 26214400'
sysctl -w net.ipv4.tcp_wmem='4096 1048576 26214400'
sysctl -w net.ipv4.tcp_mem='26214400 26214400 26214400'

EOF
sed -i '/^\s*$/d' tune.sh
sync
reboot

####################################


Measure 9 - Assign squeezelite to isolated CPU1

In Measure 2 we isolated CPU0 - actually we also isolated CPU1 already.  
The idea was to have all interrupts running on CPU0 exclusive. 
Now we're going one step further. We are going to assign squeezelite to a 2nd CPU CPU1 exclusive. CPU0 and CPU1 will then be used exclusively. 
The remaining 2 CPUs will be used for anything else that's going on. Which is not much. However. We try to leave no stone unturned with this exercise.

##################################
sudo su
cd /mnt/mmcblk0p2/tce
cat <<"EOF" >>tune.sh
sleep 1
taskset -cp 1 $(pgrep squeezelite)
EOF
sync
reboot
##################################


Measure 10 - Assign a higher priority to squeezelite 

During the squeezelite settings exercise we added "-p 45" to the settings.
With this we elevated the priority of just the output thread of squeezelite to 45.
The other three threads - the squeezelite process spawns 4 threads - are running 
at normal non-elevated priorities by default. Now we gonna lift these three too.

There's a range of 1-99 of priorities. If you start changing the priorities of processes
you have to make sure that a proper ranking stays in tact. E.g. the dwc_otg interrupts
being in charge for network and USB are fixed at prio 51. We simply shouldn't go
beyond that limit.


Now. The output thread has prio 45, using prio 44 for the rest of squeezelite will do.    

##################################
sudo su
cd /mnt/mmcblk0p2/tce
cat <<"EOF" >>tune.sh
sleep 1
chrt -f  -p 44 $(pgrep squeezelite)
EOF
sync
reboot



################################## 

Done!

........................................................................................................................................................


Wrap-Up

Hopefully you made it all the way down here. I'm pretty sure you did. 
I'm pretty confident you'll enjoy the result.


Don't forget to make a backup of your SD-card after this exercise!


**********

I rely on your feedback to get above
working reliable. 
For me above commands and actions are daily work. I have a hard time anticipating your potential issues in running this exercise.
I'd really appreciate if you'd just drop me a line, confirming that everything worked as
I assumed it would. Or you tell me that it isn't working and tell me what you've done.

Enjoy.

1 comment:

  1. Hi, I'm finding your blog both useful in tuning my Rpi3 with Picoreplayer and technically very interesting.

    ReplyDelete