改进思路的更详细描述(只描述1楼没写的)(如有不同意见希望不吝赐教):
zram 的算法选择(本文的算法选择分析只针对标准内核,
特殊情况请阅读本链接):
由于
zram算法特点,我们最先排除掉压缩慢压缩效果也不好的lz4hc和lz4
选取两个最具代表性算法在本文对比:lzo(默认算法,压缩效果和速度都相对不错),deflate(最慢,也是压缩效果最好的算法)
折腾了半天,两者好像不能简单的说谁比谁好或优先尝试谁,要根据实机环境和需求决定
根本原则是最大化系统速度
lzo尽管自身很快,但问题是压缩率低,导致低内存环境下会更多丢弃缓存,甚至更多发生OOM,
deflate尽管很慢,但在我模拟老机的测试中使用 deflate 算法的 zram 响应速度仍明显快于使用HDD的交换文件.
但在模拟老机的测试中使用lzo算法,oom 就发生较为频繁.
测试负载就是LXDE+打开Firefox浏览几个图文网页
模拟老机=(禁用多核,CPU节能全开并以最低频率运行,用内核参数"mem=384M"限制内核的内存使用)
关于如何选择算法下面给出一些个人的建议:
Tue Sep 5 14:52:04 CST 2017{
进行了更多的尝试,deflate卡CPU没那么严重,卡CPU的主要原因是VirtualBox设置的虚拟机内存太小导致类似卡在kswapd0的情况.
想办法降低虚拟机系统的内存消耗或适当稍微调高虚拟机的内存,CPU占用率明显下降.
尽管不太确定,感觉在一些测试下设置为lzo算法更容易让整个系统卡住,deflate卡的没lzo那么彻底.
我会在方便时贴出
具体测试方法}
1.如果内存资源只是稍微短缺,同时CPU资源也稍微紧张,那么lzo更合适
"内存稍微短缺"具体对我个人来说就是开虚拟机,内存没zram也基本够用(很少发生OOM之类的事情),只是会大量丢弃缓存造成响应速度大幅下降.
而开虚拟机本身也是一个CPU密集型的负载,所以个人感觉使用lzo对我自己这种情况更合适
2.内存十分紧张,但没有CPU密集型的任务或负载,可以优先考虑使用deflate.
swap_cache_pressure是一个目前(Debian Strethc 4.9内核)失败的尝试
想法是把zram分割成多个较小的swap设备,当时以为这样就容易迫使内核释放swap_cache
但最后仔细看内核代码,是整个VM(全部swap空间)可用空间低于50%时才释放,而非单个swap设备
swap_cache 对 zram 理论上也有提速作用,只不过zram通常速度很快,体现不出来.
同时内核自己本身也会在整个VM(全部swap空间)可用空间低于50%时释放swap_cache页面变脏时swap_cache也会被释放所以完全没必要担心swap_cache参阅:
http://elixir.free-electrons.com/linux/ ... ile.c#L576http://elixir.free-electrons.com/linux/ ... wap.h#L392vm_swap_full 中 nr_swap_pages 和 total_swap_pages 的含义:
https://www.kernel.org/doc/gorman/html/ ... nd028.html关于per-CPU zram:
似乎新版本内核已经不需要这种措施了引用:
Set max number of compression streams
Regardless the value passed to this attribute, ZRAM will always
allocate multiple compression streams - one per online CPUs - thus
allowing several concurrent compression operations. The number of
allocated compression streams goes down when some of the CPUs
become offline. There is no single-compression-stream mode anymore,
unless you are running a UP system or has only 1 CPU online.
在4.9内核甚至不需要设置max_comp_streams我用time
zramswaptest.c 测试时间时per-CPU zram 甚至比单个zram稍慢(差别非常微弱,懒得贴测试结果了,谁要是纠结可以自行按照我说的方法实验)
vm的参数调整参考内核源码树里的vm.txtecho 100 >/proc/sys/vm/swappiness
swappiness等于100时将file和anonymous页面设置为同等优先级
swappiness小于100时则倾向于优先通过释放文件缓存避免使用swap空间swappiness扩展阅读echo 0 >/proc/sys/vm/page-cluster
禁用swap预读,每次只读取一个需要的页面,zram 自身设备延迟非常低,绝大多数时间都是花费在实际读取page-cluster默认是8
另一些信息显示在使用zram作为交换设备的情况下默认的page-cluster=8可能导致内存浪费echo 0 >/proc/sys/vm/extfrag_threshold
完全是我自己根据 vm.txt 里的介绍意淫出来的优化措施,没有任何参考资料和测试
目的是尽可能避免因碎片导致内存分配失败.
echo 1 >/proc/sys/vm/watermark_scale_factor
这个参数我还不确定我是否理解正确
结合vm.txt 里的介绍和测试结果,我对 watermark_scale_factor 的理解是其数值越大kswapd越倾向于提前尝试释放内存(释放缓存或swap-out)
如果速度设备比较慢,内存需求的增加速度又较快,这个数值似乎应该调高,此种情况会增加速度
例如将zram设置为较慢的deflate,然后用dd往tmpfs挂载点里写的大量数据(注意要用"yes 12"三个不重复的字节填充,不然可能会被zram直接去重而非压缩)
我这里是往tmpfs写了2048M数据,free显示我有总共1.9G内存
设置为1000比1要稍微快一点.
但这个测试例子很极端甚至无用.
另一个测试是往tmpfs上写入 /dev/urandom 数据(即写入不可压缩数据).
如此这样便可模拟低内存环境,我往tmpfs上写入了1600M 的 /dev/urandom 数据,后台有一个程序不停调用mplayer播放不同文件
设置为1000时可以明显看到kswapd0大量活跃,后台程序调用mplayer播放不同文件的速度也比较慢
设置为1时则立刻停止了无用的swap,后台程序的播放切换速度也跟正常使用时一样,仿佛没有内存压力.看内核代码和vm.txt 的描述,调高 watermark_scale_factor 的意义基本上等同于调高watermark(一个可用内存阀值,低于此阀值就会触发kswapd)
即使设置为deflate算法,zram 的 速度也通常足够(具体是否足够仍取决于实际速度(CPU速度,内存速度等)),因为桌面环境下swap大多是多次少量随机的进行,不会出现一次读写1600M这种情况.
我把我的E5500调到1.2GHz频率,BIOS设置为单核模式,内核限制为256M,
zramswaptest.c测试256M仍然可以完成,时间用了约40秒(记不清了,差不多吧,时间不是重点,重点是没有出现异常(例如分配失败或OOM)).
鉴于此参数设置为1没有显著降低类似dd测试(即短时间内需要大量内存的测试)的速度.
简而言之对于watermark_scale_factor,我的测试结果(deflate算法下):
watermark_scale_factor=1000 显著增加CPU消耗,且速度提升微弱(个人认为可忽略不计)
watermark_scale_factor=1 显著减少CPU消耗,且速度下降微弱(个人认为可忽略不计)
所以在我的脚本里选择watermark_scale_factor=1