pop-os / default-settings

Distribution Default Settings
Other
44 stars 16 forks source link

Auto-configure zram with optimal settings #163

Closed mmstick closed 1 year ago

mmstick commented 1 year ago

Testing

Note that you can disable and recreate the zram device with

sudo swapoff /dev/zram0
sudo rmmod zram
sudo systemctl start pop-zram

Running zramctl displays the compression algorithm, max size of block device, memory stored inside of it and its compressed size.

Rationale

Implementation

lfom commented 1 year ago

Please consider keeping things simple and using well known standards. zram-generator is a well known and documented ZRAM manager, it even allows using flexible rules to manage the amount of ZRAM according to the machine RAM:

https://github.com/systemd/zram-generator/blob/main/man/zram-generator.conf.md

Like other systemd services, it is possible to create a simple drop in file like:

/etc/systemd/zram-generator.conf.d/50-pop-zram.conf

with the desired rule (the one suggested in the link above looks very good, for both machine with low RAM and otherwise).

And sysctl values should go to the default place as well, for instance:

/etc/sysctl.conf.d/99-pop-zram.conf

This would use standards, as well as making it very easy to find where the settings are stored, and also allows user customization.

mmstick commented 1 year ago

@lfom We already have a sysctl config file for things that make sense to be applied universally by default (see the PR). In this particular case, it's not a good idea to have conditional parameters stored in a permanent configuration file.

The sysctl parameters are applied in the script because they need to be evaluated at runtime (vm.page-cluster=0 for zstd, 1 for others, 2 for SSD-based swap, 3 for swap on magnetic drives), and only applied when the system is actually using the pop-configured zram block device (vm.swappiness=180 is not ideal for traditional swap on a desktop). Performance would be negatively impacted for those who disable pop-zram.service if settings were generated and written to /etc/sysctl.d/.

As mentioned in the PR's description, I'm really not sure zram-generator is so necessary to add as a dependency when the complexity isn't needed for a system default. If someone wants a more complex setup, they could add zram-generator to their system and use that instead. And this way it's easier to opt out of the Pop config.

I'm also trying to avoid including any config files that are not easily disabled. I only have one optional user-defined env file at /etc/pop-zram to override the default parameters. Distribution default configuration files are placed into /usr/ and overwritten or rewritten on every package update. So a user can't easily disable the config provided by the distribution, unless the service has some way of masking configs.

I'm a fan of simple solutions. This is a pretty basic 20 line bash script to automatically evaluate and apply the recommended system defaults. At it's core, we're talking about a script that's just running

modprobe zram num_devices=1 && sync
zramctl --size "${SIZE}M" --algorithm "${ALGO}" /dev/zram0
mkswap /dev/zram0 && sync
swapon -p "${PRIORITY}" /dev/zram0
sysctl -w "vm.page-cluster=${PAGE_CLUSTERS}" "vm.swappiness=${SWAPPINESS}"

Regardless, we'd still need a system service to apply the sysctl tweaks when using the default configuration provided by Pop.

lfom commented 1 year ago

If the main reason for doing all this is to check the current user configuration for systems already running Pop!_OS, then this can be done during the package installation. This would prevent problems for any user who already changed the default swap configuration IMO. Besides the additional rules in the post-installation script to check the current swap configuration, it would require only enabling zram-generation and placing the two text configuration files.

benuski commented 1 year ago

Enabled this on my HP Dev One with 64gb of RAM. Everything is working as expected with no performance degredations. It currently feels a bit snappier under a basic load, and I'll continue to test it with more intensive things.

woutheijnen commented 1 year ago

Thank you for this great find, it works wonderfully on my PC with 8GB RAM, and I got a solid boost from sometimes 80 fps to 120fps (my refresh rate) and other times from 80fps to 90 fps. I have various pcs with different amounts of RAM available, currently on 8GB and 16GB it works good, 4GB shows some good things too but want I need to test it a bit more though I think. The 4GB pc doesn't run Pop OS though, it runs Mint with xfce. Also want to try out on a 2GB pc to see how it runs, but will see when I get the time to install it as it currently doesn't run anything.

I have a burning question for some time though and this seems like a good moment to ask it : Pop by default enables zswap and it defaults to lzo/zbud, but wouldn't it be better if it would default to zstd/z3fold ? Or lz4/z3fold ? I used to play Cities Skylines which is a very memory heavy game when you get all the dlc + mods as it loads all assets to RAM, but even with my pc of 8GB RAM, it managed to be completely playable with lz4/z3fold (haven't tried zstd). I also use the package swapspace to automatically create swap if necessary and this made it so 12-14GB was loaded in swap (on ssd) + 8GB in RAM and the game was perfectly playable at around 50fps and rarely crashed. The only issue with the package swapspace I had was on my work pc when I dumped a self referenced variable with print_r in PHP, and it started to explode in memory and thus in disk size (easily 40+GB RAM in about a minute), but normally swapspace has configuration options to limit the amount of space it can take.

So maybe those are some other optimizations that can be made by defaulting to zstd/z3fold and by using a tuned swapspace package (instead of running out of memory as is the default case currently) for Pop.

mmstick commented 1 year ago

@woutheijnen This defaults to zstd

woutheijnen commented 1 year ago

@woutheijnen This defaults to zstd

I know but it defaults to zstd for zram only, not for zswap. When you boot up your pc and execute journalctl | grep zswap it says : zswap: loaded using pool lzo/zbud

This is for a similar optimization (zswap) to maybe make it default to zstd/z3fold instead of lzo/zbud and maybe swapspace could be handy too for Pop_Os systems in case of systems having low RAM just an optimization suggestion

Mirppc commented 1 year ago

FYI the settings for Zram will change the defaults for normal swap too. So if Zram is disabled the existing zram swappiness settings are left causing swap to be prioritized over ram.

ahydronous commented 1 month ago

@mmstick it could be a consideration to:

The reason I say this is because of the charts in the Reddit post you linked: https://imgur.com/a/linux-zram-benchmarks-bUSBlm1. Or was extensive profiling done by the Pop team?

zstd has horrible access times compared to lz4, and generally for system memory access times matter more than throughput. Tangential, but according to that bench, lz4 does also benefit from vm.page-cluster=0. It pays a pretty big penalty otherwise.