Hello all,
I want to share a document that I've been creating for myself. This is specifically for Fedora Workstation usage, and has not been fully tested. I have tried, where possible, to document my sources, and explain what everything does. I'm posting this for three reasons: 1. I want to have the document stored in a safe place other than my hard drive, in case of possible failures. 2. I want "constructive" criticism on the document, so that I can improve it and make changes and corrections as needed. 3. I hope others will find this information helpful and useful.
Fedora Pipewire Low Latency Audio Configuration Reference Guide v.1.02
A QUICK ACKNOWEDGEMENT NOTE:
There is hardly an original word in this document. EVERYTHING in this document that has any use or meaning has come from the writing of others. Any and all credit for the information in this document belongs to all of those who came before and paved the way of documenting how to achieve low latency with Linux. There is a lot of valuable information in these sources. One would benefit reading these documents. Used resources are:
https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Performance-tuning
https://discussion.fedoraproject.org
https://wiki.linuxaudio.org/wiki/system_configuration
https://wiki.archlinux.org/title/Professional_audio
https://fedoraproject.org/wiki/Fedora_Project_Wiki
https://forum.cockos.com/forumdisplay.php?f=52
https://linuxmusicians.com/
https://discourse.ardour.org/
https://docs.kernel.org/
https://jackaudio.org/
https://src.fedoraproject.org
https://jcwillia.fedorapeople.org
https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Performance-tuning?sm_au=iVVFVQNqpW06rVfjTvBpFLHLqs6cW
https://discourse.ubuntu.com/
https://lwn.net/Articles/652156/
https://opensource.com/article/20/6/linux-noatime
https://wiki.tnonline.net/w/Btrfs/Mount_Options#:~:text=Btrfs%20mount%20optionsedit%20edit%20source&text=noatime%20is%20useful%20to%20use,when%20you%20have%20many%20snapshots.
https://wiki.archlinux.org/title/fstab
https://wiki.archlinux.org/title/Professional_audio
https://linuxmusicians.com/viewtopic.php?t=26784
https://codeberg.org/autostatic/rtcirqus
...and probably many more!
In addition to the above resources, I also drew from numerous comments I searched and found through sources such as Reddit, Stack Exchange, Wikipedia, etc., etc., etc.
<<<<<<<<<<<<<<<<<<<<<<<<<<WARNING +++ WARNING +++ WARNING>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
This document is meant to be a quick reference for those who already know
what they are doing, but want the information in a easily accessible format for
configuring their system for low latency. This document is provided as is. There is
no support provided. Be sure you understand everything you are doing before
using this reference. Do not do any of these tweaks blindly!
<<<<<<<<<<<<<<<<<<<<<<<<<<WARNING +++ WARNING +++ WARNING>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1. Set the CPU frequency scaling governor to performance
NOTE TO SELF: It was recently announced that Fedora 41 will be moving to TuneD:
https://www.phoronix.com/news/Fedora-41-Goes-Tuned-PPD
“TuneD is incompatible with cpupower and power-profiles-daemon. If you have these services, uninstall or disable them.”
I will need to update this section to reflect these changes when they take place.
cpupower is included in kernel-tools package. Install it, if it isn't already installed.
Changing the CPU governor
Question: Before getting into modifying it, what is a CPU governor?
Answer: A CPU governor decides how the CPU raises and lowers its clock speed in response to the demands the applications place on the system. They can help in striking a balance between performance and battery efficiency or to be inclined towards either.
How do you check the list of available governors for your CPU?
Simply execute the following command:
Code: Select all
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
This should list the available governors for your CPU that you can choose from.
How do I know which governor is currently active on my CPU, should I have more than one of them?
Simply execute the following command,
Code: Select all
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
This should display the governor that is currently enabled on your CPU.
How do I increase make the CPU perform better using the governor?
Simply execute the following command:
Code: Select all
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
This sets all the cores to work on the performance governor and the CPU cycles would have an affinity towards higher clock limit.
Advantages
- GNOME would now perform significantly faster and the animations would be smoother.
- You would notice less artifacts on the GNOME panel and other applets that you use.
Disadvantages
- The device is likely to slightly heat up due to active CPU usage and fans would be rolling.
- There would be a slight impact on battery life if the CPU constantly stays on this governor.
How do I make the battery life better using the governor?
Simply execute the following command:
Code: Select all
echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
This sets all the cores to work on the powersave governor and the CPU cycles would have an affinity towards lower clock limit.
Advantages
- The device is likely to stay cooler due to minimal CPU load and fans would not be used.
- The battery life would stay the same for a long time if the CPU constantly stays on this governor.
Disadvantages
- GNOME’s performance would be adversely affected and animations would be choppier.
- You would notice more artifacts on the GNOME panel and other applets that you use.
What other CPU governors are likely to be available on my CPU?
The command specified in point #1 (How do you check the list of available governors for your CPU?) would list the available governors for your CPU but allow me to explain what each does so that you can pick the right one as per your requirement.
conservative - This makes the CPU stick to the lowest possible clock speed as much as possible but would raise it promptly, once a larger and more persistent load is placed on the CPU. This can strike a good balance between battery life and performance - being slightly more inclined towards battery life.
userspace - This allows any program to be executed by the user to decide what CPU’s operating clock speed should be. The best example is when there is a performance profile application installed by the users which needs elevated privileges to control how the CPU clock speeds scale.
powersave - This makes the CPU stick to the lower clock speed limit, thus saving a huge chunk of battery level and improving battery life but adversely affecting the performance as a result - so every applications would execute significantly slower and animations would be choppier.
ondemand - This makes the CPU boost to higher clock speeds, once a large load is placed on the CPU and slowly reduces the clock speeds once the load is removed. This can strike a good balance between battery life and performance - being slightly more inclined towards performance.
performance - This makes the CPU stick to the higher clock speed limit, thus increasing the performance significantly and making the animations smooth, however ends up adversely affecting the thermal performance, battery level as well as battery life (in a long run).
If you want to set the governor persistently, the most harmonious way of doing it is this:
Make sure kernel-tools is installed, if it isn't.
Code: Select all
sudo dnf install kernel-tools
This package provides cpupower and turbostat, both of which are invaluable when dealing with the frequency governor.
Edit /etc/sysconfig/cpupower as desired. See man cpupower-frequency-set
Then enable the new setting:
Code: Select all
systemctl enable --now cpupower.service
considerations when permanently setting your governor:
If your machine is underpowered and already being taxed, you might as well permanently set the CPU governor. The benefits are that the CPU won't have to ramp up--it will permanently have full CPU power at the ready, and you won't have to change back and forth between governor scaling settings like you would if you weren't setting the governor permenantly.
On the other hand, if the CPU is not allowed to scale back because of the governor, even when the game/application does not tax it, it still runs at full speed/voltage and as a result it has no opportunity to cool down, and this can result to the temperature building up and the CPU throttling. Also, it will use more battery, if you are running on battery power.
Do some research about governors to form your own opinion anyway.
2. Configure realtime privileges limits (AKA "PAM Limits" or "RLIMITs") and memlock
NOTE: It appears that there is a Fedora package that does this step for you, and it may be better as well, because it appears to help with latency spikes. More investigation is needed:
Configure Automatically:
https://discussion.fedoraproject.org/t/pipewire-configuration-for-low-latency/32221
https://src.fedoraproject.org/rpms/realtime-setup
https://jcwillia.fedorapeople.org/realtime-setup.spec?sm_au=iVVFVQNqpW06rVfjTvBpFLHLqs6cW
Configure details useful for low-latency environments.
Installation of this package results in:
- creation of a realtime group
- adds realtime limits configuration for PAM
- adds udev specific rules for threaded irqs and /dev/rtc access
- adds /usr/bin/slub_cpu_partial_off to turn off cpu_partials in SLUB
- adds net-socket timestamp static key daemon (realtime-entsk)
The slub_cpu_partial_off script is used to turn off the SLUB slab allocator's
use of cpu-partials, which has been known to create latency-spikes.
The realtime-entsk program is a workaround for latency spikes caused when the
network stack enables hardware timestamping and activates a static key. The
realtime-entsk progam is activated by the systemd service included and merely
enables the timestamp static key and pauses, effectively activating the static
key and never exiting, so no deactivation/activation sequences will be seen.
Neither the slub script nor realtime-entsk are active by default.
These instructions tell how to activate the slub script and realtime-entsk. See:
https://discussion.fedoraproject.org/t/pipewire-configuration-for-low-latency/32221/3
You need to install realtime-setup which will add a realtime group to /etc/security/limits.d
Code: Select all
$ sudo dnf install realtime-setup
$ sudo systemctl enable realtime-entsk.service
$ sudo systemctl start realtime-entsk.service
$ sudo systemctl enable realtime-setup.service
$ sudo systemctl start realtime-setup.service
And then add yourself to the realtime group:
Code: Select all
$ sudo usermod -a -G realtime username
(Replace the word, "username" with your own username)
Reboot your computer
Then there is this neat script by Robbert, the developer of yabridge, which takes away high priority/realtime scheduling of apps so it does not interfere with your DAW. I could not find the location so pasting here.
Code: Select all
#!/usr/bin/env bash
#
# script from Robbert Yabridge
#
# Some applications like to spawn high priority realtime threads. This can cause
# latency spikes during DAW usage.
thread_blacklist_re='^(webrtc_audio_mo|InotifyEventThr)$'
process_blacklist_re='^/usr/lib/(firefox|signal-)'
# To make it easier to see what's going on and which threads we're going to
# reschedule, we'll print all realtime threads with their thread names and the
# first part of their command, and we'll mark the threads we're going to
# reschedule.
realtime_threads=$(ps hxH -u "$USER" -o tid:30,rtprio:30,comm:30,command |
# HACK: Since thread names can contain spaces and ps doesn't have a way to
# specify a delimiter, we'll hack around this a bit by making every
# every column fixed width and then manually adding tabs. This would
# have been neater with some proper parsing, but, oh well...
# We'll also truncate the last column for readability's sake.
sed -E 's/^(.{30}) /\1\t/;
s/(\t.{30}) /\1\t/;
s/(\t.{30}) /\1\t/;
s/ +//g;
s/(\t[^ ]+)( [^\t]+)?$/\1/' |
awk -F$'\t' '($2 >= 5) {
if ($3 ~ THREAD_RE || $4 ~ PROCESS_RE) { printf "x\t" } else { printf " \t" }
print $2 "\t" $1 "\t" $3 "\t" $4;
}' THREAD_RE="$thread_blacklist_re" PROCESS_RE="$process_blacklist_re" |
column -ts$'\t')
need_rescheduling=$(echo "$realtime_threads" | awk '$1 == "x" { print $3 }')
echo "$realtime_threads"
if [[ -z $need_rescheduling ]]; then
echo -e "\nNothing to do here, modify the blacklists if needed."
else
echo -e "\nSetting all marked threads to SCHED_OTHER..."
echo "$need_rescheduling" | xargs --no-run-if-empty -n1 chrt -po 0
fi
-----------------------
If you don't want to use the realtime-setup program, you can configure these things manually:
Real-time priority limits are usually stored in /etc/security/limits.conf and /etc/security/limits.d/. The best option is to add a new file 95-pipewire.conf in /etc/security/limits.d/ with this content:
Code: Select all
# Default limits for users of pipewire
@pipewire - rtprio 95
@pipewire - nice -19
@pipewire - memlock 4194304
Then add your user to the PipeWire group so that you can use these priorities.
Code: Select all
sudo usermod -a -G pipewire username
(Replace the word, "username" with your own username)
3. Use Pavucontrol to set audio card to Pro Audio profile mode
Pavucontrol is not installed by default, but it can easily be installed through the Fedora repository or Flatpak:
Code: Select all
https://src.fedoraproject.org/rpms/pavucontrol
https://flathub.org/apps/org.pulseaudio.pavucontrol
One must be using the Pro Audio profile in order to benefit from the IRQ-based scheduling.
4. Configure Pipewire sample rate and quantum (There are GUI based programs for this too)
Quick Summary:
Use the command prompt and configure your Quantum and Sample Rate:
Code: Select all
pw-metadata -n settings 0 clock force-quantum 256
And
Code: Select all
pw-metadata -n settings 0 clock.force-rate 48000
That's it!!
Here's Wim's brief explanation:
Set a specific sample rate and buffer size?
Code: Select all
pw-metadata -n settings 0 clock.force-rate <samplerate>
Code: Select all
pw-metadata -n settings 0 clock.force-quantum <buffersize>
Confirm the actual sample rate and buffer size?
Code: Select all
pw-metadata -n settings
Reset pipewire to the default configuration?
Code: Select all
pw-metadata -n settings 0 clock.force-rate 0
Code: Select all
pw-metadata -n settings 0 clock.force-quantum 0
NOTE: There are now GUI front ends that are available that keep the user from needing to go to the command line to do any of these changes.
Deeper Explanations:
Runtime Settings
Some runtime settings can be changed with the settings metadata. You can list the current settings with:
Code: Select all
pw-metadata -n settings
Log Settings
To temporarily increase the log level of the PipeWire daemon, use:
Code: Select all
pw-metadata -n settings 0 log.level <level>
samplerate Settings
The default samplerate can be set with:
Code: Select all
pw-metadata -n settings 0 clock.rate <value>
The allowed samplerates can be set with:
Code: Select all
pw-metadata -n settings 0 clock.allowed-rates [ <value1> <value2> ... ]
To temporarily force the graph to operate in a fixed sample-rate use:
Code: Select all
pw-metadata -n settings 0 clock.force-rate <samplerate>
Both DSP processing and devices will switch to the new rate immediately. Running streams (PulseAudio, native and ALSA applications) will automatically resample to match the new rate.
Switch back to the default behaviour with:
Code: Select all
pw-metadata -n settings 0 clock.force-rate 0
Quantum Ranges
The default quantum can be set with:
Code: Select all
pw-metadata -n settings 0 clock.quantum <value>
Change the quantum ranges with:
Code: Select all
pw-metadata -n settings 0 clock.min-quantum <value>
Code: Select all
pw-metadata -n settings 0 clock.max-quantum <value>
These values are expressed against the clock.rate value. If the graph runs at an alternative rate, clock.quantum and clock.min-quantum will be scaled.
To temporarily force the graph to operate in a fixed buffer-size use:
Code: Select all
pw-metadata -n settings 0 clock.force-quantum <buffer-size>
Switch back to the default behaviour with:
Code: Select all
pw-metadata -n settings 0 clock.force-quantum 0
----------------------------------------
Simple Guide / Guide Latency
- Set lower Latency (JACK/PipeWire clients)
- Set PulseAudio clients Latency
- Set ALSA clients Latency
Set lower Latency (JACK/PipeWire clients)
The latency of the PipeWire processing graph is mostly determined by the combination of the buffer size and the sample rate of the processing graph, called the quantum.
The quantum is the amount of data (in time) that is processed per processing cycle of the graph.
By default PipeWire will select the best quantum based on the available clients and configured limits and defaults.
You can force a quantum, of for example 256, with:
Code: Select all
pw-metadata -n settings 0 clock.force-quantum 256
You can restore dynamic behaviour again with:
Code: Select all
pw-metadata -n settings 0 clock.force-quantum 0
Most PipeWire and JACK clients will directly be influenced by this value.
Set PulseAudio clients Latency
Pulseaudio clients use extra buffering in the pipewire-pulse server and so is not directly influences by the graph buffer size.
Use the environment variable PULSE_LATENCY_MSEC to suggest a latency in milliseconds.
Code: Select all
PULSE_LATENCY_MSEC=20 paplay some.wav
Set ALSA clients Latency
ALSA clients use an extra ringbuffer that can add latency.
Use the PIPEWIRE_ALSA environment variable to control the buffer size and period size of ALSA clients:
Code: Select all
PIPEWIRE_ALSA='{ alsa.buffer-bytes=16384 alsa.period-bytes=128 }' aplay ...
5. Configure generic kernel for low latency with kernel parameters
The generic kernel can be configured to act exactly like a low-latency kernel.
On recent kernels configured with PREEMPT_DYNAMIC, you can boot the kernel with and extra
preempt=full option. This effectively bypasses the compile-time settings configured for your mainline generic kernel, and allows it to make use of all of the realtime patches that have been mainlined into the generic kerel. In short, your generic kernel runs as a realtime kernel.
- NOTE: It is possible to see whether the kernel supports PREEMPT_DYNAMIC by doing a
Code: Select all
uname -a
For example:
doug@s19:~/kernel/linux$ uname -a
Linux s19 6.0.0-rc3-stock #1086 SMP PREEMPT_DYNAMIC Mon Aug 29 07:07:17 PDT 2022 x86_64 x86_64 x86_64 GNU/Linux
Another possible way is through:
$
Code: Select all
journalctl | grep '(Linux version|Startup finished.*kernel)'
With CONFIG_PREEMPT_DYNAMIC the users can overwrite that
on boot with the "preempt=" boot option.
Linux distros can be particularly fond of this because it allows them
to rely on a single kernel image for all preemption flavours.
Preempt_Dynamic has X86 and ARM support
git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks.git
preempt/arm
The PREEMPT_DYNAMIC Kconfig help text explains: This option allows to define the preemption model on the kernel command line parameter and thus override the default preemption model defined during compile time.
Right now, at least on Fedora, kernel are compiled with default voluntary preemption, where processes in kernel-mode can be preempted only at certain points, which is a step in the right direction but some kernel-heavy processes can still cause latency spikes.
Full preemption can be enabled with modern kernels that have dynamic preemption support (like Fedora's) by adding the preempt=full kernel argument. If enabled you'll see a Dynamic Preempt: full line in your dmesg.
You can verify it is on by doing:
Code: Select all
dmesg|grep preempt
See also: https://pagure.io/fedora-workstation/issue/228
New Additional Kernel boot parameter recommendations:
The new relevant kernel options can be be classified in the following categories:
kernel preemption model
kernel noise
CPU wake-up events
Kernel preemption model
The kernel provides the following preemption models, that can be changed at boot-time by passing the following options (or even at run-time via /sys/kernel/debug/sched/preempt):
preempt=full: fully preemptible kernel
preempt=voluntary: kernel can be interrupted only at specific points
preempt=none: kernel is never interrupted
A fully-preemptible kernel is most suitable for low-latency workloads - such as gaming, live-streaming, multimedia, etc. - since high-priority tasks have more chances to interrupt low-priority tasks and acquire a CPU. However, there is a cost to pay in terms of throughput with the additional preemption.
Typical server or high-performance computing workloads may prefer a less responsive kernel with fewer interruptions, yet capable of sustaining higher computational performance. In such a scenario, voluntary preemption may be preferred.
The last option (non-preemptive kernel) rarely provides benefits, only very specific CPU-intensive workloads with minimal I/O can experience improvements, such as complex image processing, or machine learning algorithms.
Kernel noise
Interrupts can introduce noise in certain latency-critical applications that can affect the expected level of performance and response predictability.
This includes hardware interrupts but also the tick interrupt: a periodic source of interruption used for timekeeping purposes and task scheduling.
The boot parameter nohz_full=<CPU_LIST> can be used to disable the periodic tick interrupt on a subset of CPUs if they run 0 or 1 task. In fact, there is no need to trigger the tick interrupt in this case; context switching is not required if just 1 task (or no task at all) is using the CPU.
This, together with proper IRQ affinity settings, can help to isolate certain CPUs from any source of interruption, providing a more predictable level of performance to the user-space applications running on such CPUs.
CPU wake-up events
In modern CPUs, power consumption is mostly determined by how often they need to leave their idle state.
The longer CPUs can stay idle, the more beneficial it is for your battery life.
Interrupts and asynchronous events that bring back CPUs to an operative state can be a significant source of power consumption.
In the kernel, a big source of wake-up events can be caused by RCUs https://lwn.net/Articles/652156/ , due to the asynchronous RCU callback execution.
In fact, RCU callbacks are used for deferred cleanup or destruction of data structures after they are no longer in use by readers. However, if a system is subject to a significant amount of changes in some RCU-protected structures, the amount of callback executions per second can be relevant and cause a lot of wake-up events.
In order to reduce the amount of CPU wake-ups a new combination of options can be used in the kernel boot parameters: rcu_nocbs and rcutree.enable_rcu_lazy=1.
The former can be used to move the execution of RCU callbacks from a softirq context to a kthread context, the latter allows you to batch RCU callbacks and then flush them after a timed delay, instead of executing them immediately.
Grouping multiple RCU callbacks together and processing them all at once can significantly reduce the rate of wake-up events and provide around 510% power-savings for idle or lightly-loaded systems.
Adding rcu_nocbs=<CPU_LIST> rcutree.enable_rcu_lazy=1 to the kernel boot parameter can enhance power efficiency, making this setting particularly interesting in a mobile / laptop context.
Performance profiles examples
Following there is a list of performance profile examples mapped to these new kernel settings:
server (use default settings)
gaming: preempt=full
virtualization: preempt=full nohz_full=all
audio: preempt=full nohz_full=all threadirqs
mobile: preempt=full rcu_nocbs=all rcutree.enable_rcu_lazy=1
Simply copy paste the options above for the desired performance profile and add them to the GRUB_CMDLINE_LINUX_DEFAULT= line in /etc/default/grub (then run sudo update-grub to apply them at the next reboot).
Additional low-latency settings
Following there are other extra run-time settings that can help to increase system predictability and responsiveness:
- set the cpufreq governor to performance via:
Code: Select all
/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
- disable proactive memory compaction:
Code: Select all
echo 0 | sudo tee /proc/sys/vm/compaction_proactiveness
- disable kernel samepage merging
Code: Select all
echo 0 | sudo tee /sys/kernel/mm/ksm/run
- trashing mitigation (prevent working set from getting evicted for 1000 millisec, this can help to mitigate stuttering behavior under memory pressure conditions):
Code: Select all
echo 1000 | sudo tee /sys/kernel/mm/lru_gen/min_ttl_ms
- prevent stuttering behavior during intense I/O writes that may involve massive page cache flushing:
Code: Select all
echo 5 | sudo tee /proc/sys/vm/dirty_ratio
Code: Select all
echo 5 | sudo tee /proc/sys/vm/dirty_background_ratio
-----
How to Configure Grub to use the Boot Time Kernel Parameters in Fedora:
Example:
Add "threadirqs" as kernel parameter
Code: Select all
sudo nano /etc/default/grub
change GRUB_CMDLINE_LINUX="" to GRUB_CMDLINE_LINUX="threadirqs"
Code: Select all
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Change GRUB
When you update your Linux system, GRUB is also updated so that when you boot, your computer loads the latest kernel. You can, however, make updates to GRUB yourself.
While /etc/grub2.cfg and the files in /etc/grub.d are reserved for automated updates, the file /etc/default/grub is for user customizations. For instance, to adjust the time it takes for GRUB to time out before the system boots to the default selection, open /etc/default/grub in your favorite text editor (using the sudo command for administrative privileges) and change GRUB_TIMEOUT from 5 to 15:
GRUB_TIMEOUT=15
Save and close the file. You've only changed a template file, not the actual data that GRUB uses when your computer boots. To integrate your change into the boot process, you must rebuild the active GRUB configuration using the grub2-mkconfig command. The path you use for output depends on your computer's firmware structure.
If your computer uses BIOS, then the (old) file /boot/grub2/grub.cfg exists, so you must replace it:
$
Code: Select all
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
If your computer uses UEFI, the file /boot/efi/EFI/fedora/grub.cfg exists, and you must replace it:
$
Code: Select all
sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
Reboot to see your change in effect.
6. Add noatime to fstab
According to the following article, noatime isn't as important as it used to be and can be skipped as tweak if you use modern drives like NVME or a fast SSD. In short: modern Linux systems (since Linux 2.6.30, released in 2009) already use relatime, which should give you a really fast performance boost. That means you don't need to tweak your /etc/fstab file and can rely on the relatime kernel default.
https://opensource.com/article/20/6/linux-noatime
The article continues:
But if you're looking to tweak your system to get maximum performance, disabling atime is still a valid option in 2020.
This performance tweak might not be very noticeable on very fast modern drives (like NVME or a fast SSD), but there's still a little boost there.
If you know you don't use software that requires atime, then you can get a slight performance boost by setting noatime in your /etc/fstab file. This tells the kernel not to track the Last Accessed time, avoiding that tiny performance hit to continually update atime in the filesystem. Add noatime as an option to your Linux filesystems, usually after the defaults entry.
See the following article for further information:
https://wiki.tnonline.net/w/Btrfs/Mount_Options#:~:text=Btrfs%20mount%20optionsedit%20edit%20source&text=noatime%20is%20useful%20to%20use,when%20you%20have%20many%20snapshots.
noatime is useful to use use by default because atime updates increases metadata writes. Atimes are especially costly performance-wise when you have many snapshots.
Btrfs has several mount options that controls how the filesystem behaves. Some are used in recovery situations and some are used for performance or quality tradeoffs.
Except for the subvol and subvolid, all mount options affect the whole filesystem, and not the individual subvolume mounts. This means, for example, that specifying compress=zstd on the first mount, all subsequent mounts, including other subvolumes, will inherit the compression option.
Generic Linux VFS mount options like atime/noatime, auto/noauto, dev/nodev, and others, do apply per mount point.
The basic mount command is mount -o <options> <device> <path>
Code: Select all
# mount -o compress=zstd,subvol=@homes /dev/sdc1 /home
More info:
https://wiki.archlinux.org/title/fstab
7. Reduce swappiness to 10
Reducing the swappiness value
- Before getting into modifying it, what is swappiness value?
Swappiness is a property for the Linux kernel that changes the balance between swapping out runtime memory, as opposed to dropping pages from the system page cache. Swappiness can be set to values between 0 and 100, inclusive. A low value means the kernel will try to avoid swapping as much as possible where a higher value instead will make the kernel aggressively try to use swap space.
- Why is “reducing” the swappiness value a good idea?
Suppose you have a system RAM with capacity of more than or equal to 16GB and a good frequency of 2400MHz or above - this should be more than sufficient to load entire programs on the memory and execute from there in most circumstances. Having a higher swappiness value in this scenario disregards all the good that the primary memory could have brought you and makes you depend on a much slower secondary memory device, as that is where the swap partition resides - thus causing a bottleneck. Reducing the swappiness value is a good idea as it would make the scheduler proactively use the primary memory as much as possible.
- Why is “increasing” the swappiness value a good idea?
Suppose you have a system RAM with capacity of less than or equal to 4GB and an okayish frequency of 2133MHz or lower - this is not at all sufficient to load even browsers completely on the memory and execute from there in most circumstances. Having a lower swappiness value in this scenario adds undue load on the primary memory which is undercapable and you are likely to frequently face out-of-memory errors due to such a configuration. The increased tendency to swap pages to the secondary storage device would allow execution of larger programs (with size larger than the primary memory) and increasing the swappiness value is thus a good idea.
- How do I check current swappiness value?
Simply execute the following command,
Code: Select all
cat /proc/sys/vm/swappiness
This would display the current swappiness value for your system which is 60 by default for Fedora.
- How do I change swappiness value?
Open /etc/sysctl.conf with a text editor of your choice.
For example sudo nano /etc/sysctl.conf
Append the following line in the file, save changes and restart your system.
- If you have a DDR4 RAM with 8GB capacity or more and a good frequency of 2400MHz or above, add - vm.swappiness=10.
- If you have a DDR3/DDR4 RAM with 4GB capacity or less and an okayish frequency of 2133 MHz or less, you need not make any changes.
8. Increase the maximum watches on files
https://wiki.archlinux.org/title/Professional_audio
Increasing the maximum watches on files (defaults to 524288) to e.g. 600000, that inotify keeps track of for your user, can help with applications, that require many file handles (such as DAWs). This again can be done on the fly with sysctl fs.inotify.max_user_watches=600000 or in a dedicated configuration file:
/etc/sysctl.d/90-max_user_watches.conf
fs.inotify.max_user_watches = 600000
9. Prioritize soundcard interrupt handling threads with rtirq, udev-rtirq, or rtcirqus script before starting your DAW
NOTE: These init-script/systemd-services makes sense only on real-time preemptive (PREEMPT_RT) kernel, or threadirqs enabled Generic GNU/Linux kernels.
NOTE: THIS SECTION NEEDS MUCH MORE WORK TO EXPLAIN WHAT THESE SCRIPTS DO, AND THE PROS AND CONS OF EACH. IN THE MEAN TIME, I'VE ADDED THE LINKS TO EACH OF THESE SCRIPTS SO THAT YOU CAN RESEARCH AND CHOOSE WHICH ONE YOU WANT TO USE FOR YOURSELF.
rtirq:
https://github.com/rncbc/rtirq
https://alsa.opensrc.org/Rtirq
udev-rtirq:
https://github.com/jhernberg/udev-rtirq
https://autostatic.com/tag/udev-rtirq/
rtcirqus:
https://linuxmusicians.com/viewtopic.php?t=26784
https://codeberg.org/autostatic/rtcirqus
10. BONUS STEP:
After all of this is done, consider running the rtcqs script to check your readiness.