Linux zram

From rdiez's Personal Wiki
Jump to: navigation, search

Introduction

zram is a Linux block device that lives in RAM and compresses any data written to it.

When created, a zram device advertises its nominal capacity as empty space but allocates no actual memory. You can then create a filesystem on the zram device and use it as a RAM disk. As data is gradually written to it, zram will allocate as much kernel memory as necessary to hold the compressed data.

Compressing data takes CPU time, but can be faster than writing to a physical hard disk. If the data happens to not compress well, zram will allocate as much RAM as all the original data. If that is always the case, then it is best to use an uncompressed RAM disk like ramdisk, ramfs or tmpfs.

Limitations

The LZO algorithm is designed for compression and decompression speed and does not achieve high compression ratios. The trouble is, zram does not attempt to recompress the data with a slower algorithm when the CPU is idle.

The administration overhead can be pretty high. Compressed data is never moved around in order to compact memory, like some garbage collectors do. Even though the underlying zsmalloc allocator is supposed to reduce fragmentation, I have seen overhead ratios between 8% and 12% of the compressed data size.

Note that, as of Kernel 3.14.4, zram conveniently forgets to include the size of the page table (called "meta->table" in the source code) in its mem_used_total performance counter. For an advertised swap size of 512 MiB, which can hold 131,072 pages sized 4096 bytes each, the page table needs 1.5 MiB of RAM on a 64-bit system. This is a small fib at just 0.293 % of unreported overhead, but the tendency to misrepresent the compression rates by leaving the admin overhead out of the calculations (see most user reports, and compr_data_size's description) is a little more worrying.

zram does not support the TRIM command, which is typically used with SSD disks. Therefore, zram will not free allocated memory even if all files are deleted. That is a little weird, because zram's predecessor project compcache does have this feature. Look for performance counter /sys/block/zram<id>/discard . Another compcache feature missing from zram is the optional backing store device.

Availability

zram was considered stable as of Linux kernel version 3.14, released in March 2014. Ubuntu 14.04 has kernel version 3.13 and its zram is still considered experimental, although it had already enjoyed widespread usage then.

The version planned for kernel 3.15 supports the alternative LZ4 compression algorithm, in addition to the default LZO. zram does NOT attempt to recompress the data in the background if the CPU is idle.

Using zram as a Swap Device

Using zram as a swap device is an interesting idea. I have not found on the Internet many performance tests yet, but most people who have tried it report an increased performance for standard office tasks, especially if the computer has little RAM. That seems like a contradiction at first, because zram uses RAM itself, making a scarce resource even scarcer.

A typical compression ratio for a zram swap file, taking all the management overhead into consideration, is factor 2.5. This means that "normal" swap data gets compressed down to a 40% of its original size. Therefore, for every byte of RAM that zram takes away, you get 2.5 bytes of a very fast swap file, at least compared to a traditional hard disk. You will also lose some CPU performance during the data compression.

Usually, one zram block device (with its corresponding swap file) is created per CPU core, in an attempt at distributing the CPU load. By the way, I heard that a future version will support multiple threads on a single device. All those swap files will have a higher priority than any other hard disk-based swap areas, so Linux will swap to zram first, and continue swapping to disk only if zram fills up.

If you have an SSD disk, zram may not offer a performance advantage. On the other hand, swapping to RAM first may avoid constant writes to the SSD and help prolong its lifetime. This applies of course to any storage type that needs wear leveling.

Note that zram can be used in embedded devices without any storage device for a standard swap file. This way, the virtual memory size can be somewhat larger than the RAM size.

How zram Swapping Works

Say your laptop has only 512 MiB of RAM and you create a 256 MiB zram swap device. At first, no swap memory is allocated at all. Linux will use any free RAM first, but at some point in time, memory pressure will build up and swapping will commence. Note that, if your computer has plenty of RAM and never swaps, enabling zram will not consume any resources.

If the kernel decides to swap out 100 MiB of RAM contents, zram will hopefully compress it down to 40 MiB (or probably even less), which means that the kernel will gain 100 MiB but lose 40 MiB at the same time compared to a non-zram scenario. Therefore, the kernel will probably want to swap an extra 40 MiB out to compensate. Again, this will cause a 16 MiB memory loss. In the end, trying to swap 100 MiB out has actually moved 166 MiB to the zram disk. The formula to calculate this kind of sequence limit is 1 / ( 1 - compressed_size_ratio ), so that, if swap data compresses down to a 40% of its original size, you end up evicting 66.6% of extra data to compensate. This domino effect only happens at the beginning, as once the zram swap space fills up, the amount of data going in and out will stabilise. In fact, swapping pages back in will immediately free their compressed versions, which could reduce or even cancel out the initial domino effect.

Laptop hard disks are very slow, and even in the worst-case scenario, writing 166 MiB to compressed RAM is probably faster than writing 100 Mib to disk. Later on, the data will need to be read back in, and that's where the speed difference really matters. Because of their high seek times, traditional hard disks are actually ill-suited for this task, as swap pages are not read in sequential blocks, but at fairly random positions. Besides, if the system is under pressure, the kernel automatically shrinks the file system cache, which also causes increased disk activity that will probably interfere with paging (assuming that you have not moved the swap area to a different drive). Keep in mind that executable pages are normally backed by a file on disk, so they are just discarded, which means paging will always cause disk activity even if the swap file is completely held in zram.

When the 256 MiB zram device fills up, it will actually have consumed 102 MiB of RAM. Therefore, you can look at the situation this way: when under pressure, the system has lost 102 MiB of RAM, so it can only use 410 MiB instead of the physical 512 MiB. In return, the system has gained 256 MiB of very fast swap space.

If your software permanently accesses 450 MiB of memory, zram will drastically reduce performance. But that's not the normal scenario. Typically, if you keep a number of big applications like Firefox or LibreOffice running all the time, you will probably experience heavy swapping whether you have 410 or 512 MiB of physical memory. That kind of software does not need all of the allocated memory all the time, so, as long as your virtual memory needs do not exceed 666 MiB (that is 410 + 256), then zram will probably make your system faster overall. If your software needs more than 666 MiB, it will start paging out to disk, and that part will be as slow as before.

The trick is to achieve the right trade-off between RAM size, CPU performance, virtual memory requirements and hard disk speed. Your mileage may vary.

First Impressions about zram's Swap Performance

I did a quick test on an old PC of mine with the following specs:

  • AMD Athlon 64 X2, dual core, underclocked at 1.6 GHz due to excessive heat.
  • 512 MiB of RAM (grub limit, the PC has 2 GiB)
  • Old PCI VGA, ATI mach64, desktop compositing turned off.
  • 160 GB hard disk
  • Xubuntu 14.04

I started the following applications:

  • Firefox with www.devtal.de (one longish web page)
  • LibreOffice Writer and Calc with empty documents
  • Synaptic package manager
  • KSysGuard system monitor
  • One Terminal

Just switching between the applications always causes heavy paging the first time around, and my subjective impression was that performance was slightly worse with zram enabled. The 256 MiB zram device was not enough and another 126 MiB's worth of swap data landed on disk. I was surprised how quickly the swap data size grew when the system was under pressure. I never thought you would need so much virtual memory to run that set of applications.

I then tried reducing the swappiness from the default 60 to 10, and that drastically increased responsiveness. The swap data size got cut down too. Enabling zswap made the swap waiting time more frequent and longer. The compression rates varied between 2.50 and 3.28 (taking all management overhead into account).

The next thing I tried was swapping to a USB 2.0 memory stick with the following specs: 4.70 MiB/s write, 23,3 MiB/s read, 0.9 ms seek time. I noticed some improvement, but only when swappinness was set back to 60. The hard disk still rattled quite a lot, even though the system was only paging to the USB memory stick. The USB stick was apparently not fast enough.

Firefox was the application that caused the most swapping and really killed performance. Switching to Midori brought a big improvement, as long as I did not open a second web page. I tried Dillo, which was very fast, but I found its interface unusable nowadays. Starting Chromium rendered the PC unresponsive for minutes. Eventually, the system killed one of the Chromium processes and complained about lack of memory, even though the machine still had 2 GiB of swap file available.

Swap Device Usage and Implemented Optimisations

Not all of the zram device will be used. Sometimes, the kernel reserves swap page slots but never actually uses them, which is the reason why the swap usage reported by "cat /proc/swaps" differs from the data size reported by "cat /sys/block/zram<id>/orig_data_size". Many pages are shared but need to be unfold if they are written to. For more information, see copy-on-write and configuration setting /proc/sys/vm/overcommit_memory . As a consequence, the theoretical zram capacity will probably never be reached, but at least no RAM will be allocated for that reserved but unused capacity either. I can think of the following optimisation in Linux's virtual memory manager: allocate unused page slots in the lowest-priority swap device, and, when the page is actually written to disk, try to allocate it in the highest-priority device available instead.

The Linux kernel implements a small optimisation when swapping to zram called "swap free notify". When a swap page is read back in, the system normally keeps the copy on disk allocated. If the same page gets swapped out again and was not modified in the meantime, it can be discarded from memory, as the copy on disk is still valid. Look for "SwapCached:" in file /proc/meminfo for more information. However, if the swap device is based on zram, zram's copy is discarded as soon as the page is read back in, in order to free the memory used to hold the compressed version.

zram scans every page in order to check whether it contains only zeros. This makes sense if you expect filesystems to overwrite old contents with zeros in order to wipe sensitive data on disk, but I was surprised to see zeroed pages when using zram as a swap device. I would have thought that Linux' virtual memory manager would implement such a basic optimisation itself. If the system wants to wipe the swap file, overwriting large sequential blocks during shutdown would probably be a better approach.

How to Create a zram-based Swap Device on Ubuntu Systems

On Ubuntu 14.04 and derivatives, install package zram-config, which will create a zram swap device with an advertised capacity of 50% of the physical memory size. The package name is a misnomer, because you can use zram for other purposes, so it should be called "zram-swap-enabler" instead. This is how to install zram-config from a command console:

apt-get install zram-config

You can verify that it has been enabled by looking for "zram" in the list of swap devices:

cat /proc/swaps

In order to uninstall zram-config, you need to "completely remove" it, or use apt-get's "--purge" switch. Otherwise, the zram device will disappear immediately only to silently come back after a reboot. I would consider that a bug in the zram-config package. For example:

apt-get remove --purge zram-config

If you forgot to do that, you can install it again and then purge it. Or you can just "completely remove" it in Synaptic, but then the zram swap device will only be gone after a system restart.

Alternatives

zswap takes the cache approach instead, so it always needs a swap device underneath. It is more flexible, as it can dynamically cache any part of the swap file, no matter how much RAM the computer has. News site lwn.net has an article titled In-kernel memory compression about it. Note that Ubuntu 14.04's stock kernel does not support zswap.

If your system is low on memory, see my Linux Ramblings Page for more suggestions.