Jimmy Chen

A Programmer

(原创)zram算法比较以及zstd移植

  zram类似压缩饼干,是将RAM中暂时不用的部分RAM使用压缩算法压缩后,在写会RAM中,以达到RAM释放的功能。zram是一个块驱动,源码在kernel根目录下的drivers/block/zram下,相关源码这里不做分析,这篇就简单做一下压缩算法性能的对比。这次主要对比的算法是lzo、lz4和自行移植的zstd,不过目前自行移植的zstd算法还是有问题,尝试了各种方法都没办法fixed,所以就放出来当做zram算法移植指导嘛。后面有时间再讲这个bug fix掉吧。

前言

  要做对比,当然需要比较方法。这里用我司的手机作为测试工具了,手机的CPU为MSM8953,2G RAM,16G ROM。测试压缩读写速度的工具在AOSP的源码就有提供了,源码路径为system/extram/zram-perf,source lunch后通过mmm即可编译得到zram-perf工具。如果要比较算法压缩率的话,可以通过在手机上打开大型程序,然后查看/sys/block/zram0/mm_stat,进行比较。

  读写速度的获取,通过连续执行zram-perf三次,获取平均值。压缩率通过开启一个大型程序后连续读取两次mm_stat的数值,然后将程序放到后台后再开启另一大型程序,再次读入mm_stat的数值。mm_stat的各个数值代表如下:

第一个数值为原始数据大小,第二个数值我压缩后的数值大小,压缩率可以通过第一个数值除以第二个数值即可。

  如果这种测试手段存在问题的话,还请各位指出。

lzo

获取到的数据如下:

lz4

获取到的数据如下:

lzo vs lz4

  按照上面的数值来看,貌似两种压缩算法的读写速率相差不大,但是压缩率貌似是lzo更胜一筹。这里存疑,毕竟网上多有说lz4的性能更好,一方面可能是内核内置的lz4算法版本较低或者压缩级别较低,其次可能是因为测试手段有问题。

移植zstd

  zstd是Facebook开发的新一代压缩算法,在不牺牲压缩读写速度的前提下,拥有更高的压缩率。而且源码是开源的,所以可以将其移植到Linux内核上。只是博主现在移植后的zstd并不能很好的工作,所以这里贴出来和大家讨论讨论,另外看有没有大神指点下问题出在哪里了。

  要移植zstd首先是获取zstd的源码。zstd的源码,Facebook已经将其开源到GitHub上了,大家可以通过git clone https://github.com/facebook/zstd.git来下载zstd的源码。然后在zstd源码路径contrib/linux-kernel下有6个patch文件,我们将0001、0002和0005这三个patch文件复制到内核源码的根路径下,然后通过下面三条指令将patch打上:

  打上上面三个patch后,还要做如下修改:

1.对crypto/zstd.c做如下修改:

2.其次在crypto的Makefile中查看是否有如下一行,如果没有就添加上

3.接着需要到driver/block/zram目录下给zram添加zstd算法了,需要添加的代码可以模仿lz4进行添加,将下面的一个文件保存到driver/block/zram目录下,命名为zcomp_zstd.c

将下面一个文件保存为zcomp_zstd.h

然后还要对driver/block/zram目录下做如下修改:

4.最后在对应的kernel defconfig文件中添加如下内容,然后编译boot.img即可

5.启动手机后,可以通过cat /sys/block/zram0/comp_algorithm可以看到有zstd的出现,然后选中zstd即可。

zstd出现的问题

  目前移植的zstd还是有点问题的,但是博主自己分析了一周也不知道问题点出现在哪里,表示很郁闷。出现问题的现象就是:启用zstd后,打开应用使用一段时间后,cat /sys/block/zram0/mm_stat后会发现第一个数值和第二个数值相差无几,这表明数据没有被压缩到。所以就觉得异常的奇怪,因为代码也是参考zstd中的代码进行编写的,也看不出哪里有问题,奔溃。希望哪位大神知道原因可以给我留言。

  1. ben说道:

    hi 博主,
    我也准备在4.9的kernel上移植,不过有个问题,请教下:
    编译出错
    crypto/zstd.c:23:39: fatal error: crypto/internal/scompress.h: No such file or directory
    #include
    您这边是直接去掉scompress,这个主要作用是啥?

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注