DEV Community

Cover image for Let's fine tune your zRAM AKA Free RAM in openSUSE with Zstandard AKA zstd
Archer Allstars
Archer Allstars

Posted on • Updated on

Let's fine tune your zRAM AKA Free RAM in openSUSE with Zstandard AKA zstd

UPDATE: As of Tumbleweed's snapshot 20220914, my request has been merged to the upstream repository. Therefore, people on Tumbleweed can get the ultimate zRAM with the normal sudo zypper install systemd-zram-service && sudo zramswapon. However, people on Leap will have to install the new zRAM package from the upstream repository.

UPDATE2: After enabled zRAM, it's recommended to change vm.page-cluster to 0 and vm.swappiness to 180 to make the most out of your zRAM. You can permanently change both values by opening /etc/sysctl.conf file, then putting vm.page-cluster=0 and vm.swappiness=180 onto different lines.

Hi readers, the last time we met, I told you why zRAM should be enabled by default. And fortunately, enable zRAM on openSUSE is extremely easy. All you need to do is open the terminal, and enter this command:

sudo zypper install systemd-zram-service && sudo zramswapon
Enter fullscreen mode Exit fullscreen mode

Then, open YaST Services Manager, and make zramswap service to start on boot. Now, you should have a zRAM enabled system.

Well, what's the problem with this setup?


Too many zRAM devices are created

Urban Building

After you enabled zRAM with the above command, if you check your zRAM status with sudo zramctl, you will notice that there are a lot of zRAM devices created, from /dev/zram0, /dev/zram1, /dev/zram2, and so on, depends on your CPU cores. This is because, in the past (before kernel 3.15), there's no multi stream functionality exist yet. Therefore, this was the only way to parallelize the task at that time.

However, this setup is deprecated and not considered a good practice anymore. Because, since kernel 4.7, zRAM will always allocate multiple compression streams - one per online CPU - thus allowing several concurrent compression operations. Moreover, by having a lot of zRAM devices created and mounted at boot time can slow down the boot considerably, as reported here. Therefore, you should only have one zRAM device at a time, but have multiple compression streams instead. For instance, if you're using AMD Ryzen Threadripper 3990X, you should have 128 compression streams on your /dev/zram0, not 128 zRAM devices to bombard your lsblk 😂

If you check at systemd-zram-service's package repository, you will see that the script corresponding to create zRAM devices was written over 10 years ago!


The compression algorithm is outdated

Old Computers

The default zRAM compression algorithm is lzo-rle, which has high compressed swap allocations, but has low compression ratio, thus prone to OOM. While zstd, which is an open source compression algorithm backed by Facebook, may has a lower compressed swap allocations rate, but it has a much higher compression ratio. Therefore, at the end of the day, not only zstd is the most efficient compression algorithm to use, but it will also finish the compression task faster than lzo-rle due to its compression ratio advantage. You can see more about zRAM's compression algorithm benchmarks here.

I recommend everyone who uses zRAM to switch over to zstd.


Let's go faster and better, fix the issues to get our hands on the ultimate zRAM!

The Man Playing Tennis

You have to nautilus admin:/// and search for zramswapon script to make our change. This is the current systemd-zram-service's zramswapon script:

#!/bin/bash

# get the number of CPUs
num_cpus=$(grep -c processor /proc/cpuinfo)
# if something goes wrong, assume we have 1
[ "$num_cpus" != 0 ] || num_cpus=1

# set decremented number of CPUs
decr_num_cpus=$((num_cpus - 1))

# get the amount of memory in the machine
mem_total_kb=$(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')
mem_total=$((mem_total_kb * 1024))

# load dependency modules
#modprobe zram zram_num_devices=$num_cpus
# Determine module parm
mod_parm=$(modinfo zram |grep parm |tr -s " " |cut -f2 -d ":")
modprobe zram $mod_parm=$num_cpus

# initialize the devices
for i in $(seq 0 $decr_num_cpus); do
echo $((mem_total / num_cpus)) > /sys/block/zram$i/disksize
done

# Creating swap filesystems
for i in $(seq 0 $decr_num_cpus); do
mkswap /dev/zram$i
done

# Switch the swaps on
for i in $(seq 0 $decr_num_cpus); do
swapon -p 100 /dev/zram$i
done
Enter fullscreen mode Exit fullscreen mode

It tries to get the number of CPU cores first before initializing zRAM devices. We don't want that since we only need one zRAM device. Therefore, here's my zramswapon script, nice and simple:

#!/bin/bash

# get the amount of memory in the machine
mem_total_kb=$(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')
mem_total=$((mem_total_kb * 1024))

# load the dependency module
modprobe zram

# initialize the device with zstd compression algorithm
echo $mem_total > /sys/block/zram0/disksize

# Creating the swap filesystem
mkswap /dev/zram0

# Switch the swaps on
swapon -p 100 /dev/zram0
Enter fullscreen mode Exit fullscreen mode

Lastly, we want to use zstd as our compression algorithm. However, once the device is initialised, there is no way to change compression algorithm. See more about this here. Therefore, we will also have to choose the compression algorithm when we initializing zRAM device:

#!/bin/bash

# get the amount of memory in the machine
mem_total_kb=$(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')
mem_total=$((mem_total_kb * 1024))

# load the dependency module
modprobe zram

# initialize the device with zstd compression algorithm
echo zstd > /sys/block/zram0/comp_algorithm;
echo $mem_total > /sys/block/zram0/disksize

# Creating the swap filesystem
mkswap /dev/zram0

# Switch the swaps on
swapon -p 100 /dev/zram0
Enter fullscreen mode Exit fullscreen mode

With our new zramswapon script, we will have a single zRAM device (/dev/zram0) equal to the size of our physical RAM with zstd compression algorithm. You will either have to reboot your PC to see this change since the script only run on boot time, or you can just call sudo zramswapoff and sudo zramswapon again to see the effect with sudo zramctl.

However, I recommend you to fork the official systemd-zram-service repository on OBS (Open Build Service), so your script won't get overwritten when you update the package, especially, if you're on Tumbleweed that a new snapshot usually overwrites system files. You can see how to use OBS here.

Well, you can also use systemd-zram-service package on my repository by:

sudo zypper remove systemd-zram-service && sudo zramswapoff
Enter fullscreen mode Exit fullscreen mode

Then, go to my repository's download page > right-click at the download button corresponding to your OS > save link as... > double-click the file to install in YaST. And don't forget to enable zramswap service to start on boot.

I have created a request to make this change upstream, so you won't have to add my repository. Let's hope it will be accepted soon.


I think this's it for today. I hope this is a good read. If you have any comment, please let me know down below. See you later, bye 💨


Cover photo by Ralfs Blumbergs on Unsplash

Urban Building photo by Meriç Dağlı on Unsplash

Old Computers photo by Alex Motoc on Unsplash

The Man Playing Tennis photo by Moises Alex on Unsplash

Oldest comments (2)

Collapse
 
benedictjohannes profile image
benedictjohannes

Hi, I've just installed the zram service on my freshly installed opensuse tumbleweed. Your change request has been merged, and the zramswapon script is as you have updated. As a user hating to see zram devices on my lsblk, I thank you for your contribution.

Collapse
 
archerallstars profile image
Archer Allstars

Thanks. I'm glad it helped 🔌