ELT.ZIP
团队,ELT<=>Elite(精英),.ZIP为压缩格式,ELT.ZIP即压缩精英。6个地方
的同学,我们在OpenHarmony成长计划啃论文俱乐部
里,与华为、软通动力、润和软件、拓维信息、深开鸿
等公司一起,学习和研究操作系统技术
…@[toc]
① 2月23日 《老子到此一游系列》之 老子为什么是老子 —— ++综述视角解读压缩编码++
② 3月11日 《老子到此一游系列》之 老子带你看懂这些风景 —— ++多维探秘通用无损压缩++
③ 3月25日 《老子到此一游系列》之 老子见证的沧海桑田 —— ++轻翻那些永垂不朽的诗篇++
④ 4月4日 《老子到此一游系列》之 老子游玩了一条河 —— ++细数生活中的压缩点滴++
⑤ 4月18日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——一文穿透多媒体过往前沿++
⑥ 4月18日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——这些小风景你不应该错过++
⑦ 4月18日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——浅析稀疏表示医学图像++
⑧ 4月29日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——计算机视觉数据压缩应用++
⑨ 4月29日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——点燃主缓存压缩技术火花++
⑩ 4月29日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——即刻征服3D网格压缩编码++
⑪ 5月10日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——云计算数据压缩方案++
⑫ 5月10日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——大数据框架性能优化系统++
⑬ 5月10日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——物联网摇摆门趋势算法++
⑭ 5月22日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——电子设备软件更新压缩++
⑮ 5月22日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——人工智能短字符串压缩++
⑯ 5月22日 ++【ELT.ZIP】OpenHarmony啃论文俱乐部——多层存储分级数据压缩++
FSST思想内核
FSST的演化
FSST与LZ4对比
亲手复现FSST
********** | ******************** | ******************** | ******************** | ******************** | ******************** | ******************** | ******************** | ******************** | ******************** | ******************** | ******************** | ******************** | ******************** | ******************** | ***************** |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
场景 | 自动驾驶 / AR | 语音信号 | 流视频 | GPU 渲染 | 科学、云计算 | 内存缩减 | 科学应用 | 医学图像 | 数据库服务器 | 人工智能图像 | 文本传输 | GAN媒体压缩 | 图像压缩 | 文件同步 | 数据库系统 |
技术 | 点云压缩 | 稀疏快速傅里叶变换 | 有损视频压缩 | 网格压缩 | 动态选择压缩算法框架 | 无损压缩 | 分层数据压缩 | 医学图像压缩 | 无损通用压缩 | 人工智能图像压缩 | 短字符串压缩 | GAN 压缩的在线多粒度蒸馏 | 图像压缩 | 文件传输压缩 | 快速随机访问字符串压缩 |
开源项目 | Draco / 基于深度学习算法/PCL/OctNet | SFFT | AV1 / H.266编码 / H.266解码/VP9 | MeshOpt / Draco | Ares | LZ4 | HCompress | DICOM | Brotli | RAISR | AIMCS | OMGD | OpenJPEG | rsync | FSST |
快速静态符号表(FSST)压缩,这是一种轻量级的字符串编码方案。
::: hljs-left
• 字符串在现实世界的数据集中很普遍。它们通常占用大量数据,处理速度很慢。
• 在许多真实的数据库中,很大一部分数据是用字符串表示的。
• 这是因为字符串经 常被用作各种数据的万能类型。
• 人工生成的文本(描述或评论字段)
:::
• 机器生成的标识符(url、电子邮件地址、IP 地址)
• 字符串通常是高度可压缩的,许多系统依赖字典来压缩字符串。 但是字典压缩需要完全重复字符串来减少大小,因此当字符串相似但不相等时,字典压缩没有优势。存储在数据库中的大多数字符串每个字符串通常小于 30 字节。LZ4 就不适合压缩小的、单个的字符串,因为它们需要达到 KB 数量级的输入大小才能获得良好的压缩因子。但是,数据库系统通常所需是对单个字符串随机访问,而LZ4算法是通过对数据块的访问实现的,这就无法满足数据库系统的需求。
• 随机访问(解压缩单个字符串而无需解压缩一个更大的块的能力)
• 快速解码(≈1-3 周期/字节,或 1-3 GB/s 每个核)
• 文本字符串数据集的良好压缩因子(≈2×)
• 高编码性能(≈4 个周期每字节,或≈1 GB每秒每字节)
• 是用 1 字节代码替换频繁出现的最多 8 字节的子字符串,这些元素构成一个不可变符号表。
• 数据库系统轻量级压缩
的研究集中在整数数据
,但字符串在现实工作负载中的普遍存在和性能挑战需要进行更多的研究。 压缩字符串最常用的方法是使用
字典重复数据删除
。字典将每个唯一的字符串映射为整数代码,使用整数压缩方案对这些代码进行压缩。在大多数数据库系统中,字符串本身没有被压缩。
增量前缀压缩
的保序字符串
字典。共享前缀
,这使得该方案无效。全局字典还有如更新昂贵
等缺点,这阻碍了它们的广泛采用。LZ78的变体
,允许解压单个字符串
。 但是,这种方法的解压缩非常昂贵
,对于平均长度为 19 的字符串,需要超过 1 微秒的时间。这相当于每个字符大约 100 个 CPU 周期或每秒几十兆字节,这对于许多数据管理用例来说太慢了。“超大属性存储技术”(TOAST)
的方法。大于 2 KB 的进行压缩,较小的值保持不压缩。允许解压缩单个短字符串
的压缩方案之一。它首先对数据执行一次完整的传递,确定哪些字节值没有出现在输入中,并计算每对字节出现的频率。然后用未使用的字节值替换最常见的字节对。重复这个过程, 直到没有更多未使用的字节。字节对对未使用字节的依赖意味,给定一个现有的压缩表,不可见的数据不能被压缩。字节对的递归性质使解压缩迭代,速度很慢
。随机访问压缩格式
,它递归地构造层次符号语法
。初始语法由所有单字节符号组成,通过将源文本中频率最高的连续符号对替换为一个新符号、相对于扩展的语法重新计算所有符号对的频率,并递归地进行扩展。公共子字符串
(称之为符号),并将它们替换为短的、固定大小的代码, 由于效率的原因,符号的长度在 1 到 8 字节之间,并在字节(而不是位)边界上进行标识。代码总是 1 字节长,这意味着最多可以有 256 个符号,其中一个码被保留为转义码
.数组查找
转换为其符号,并将符号追加到输出缓冲区。为了有效地解压缩,将每个符号表示为一个 8 字节(64 位)的单词,并将所有符号存储在一个数组中。此外,还有第二个数组,用于存储每个单词的长度。使用这种表示,可以无条件地将 64 位字存储到输出缓冲区中,然后将输出缓冲区向前推进符号的实际长度来解压代码, 依赖于现代处理器上可用的快速未对齐存储
,这种实现需要很少的指令
,而且没有分支
。它的缓存效率也很高
, 因为符号表(2048 字节)和长度数组(256 字节)都可以轻松地 放入一级 CPU 缓存中。1.使用转义字符的优势
PS:(转义码并不是严格必要的;也可以只使用那些没有出现在输入字符串中的字节作为代码)
直接原因:保留代码 255 作为转义标记,表示输入中的以下字节需要按原样复制,而不需要在符号表中查找。
三个优点
(1)支持使用现有的符号表压缩任意
(看不见的)文本。
(2)允许在数据样本
上执行符号表构造
,从而加速压缩。
(3)它释放
了原本被保留为低频字节的符号
,从而提高了压缩因子
。
2.连续注入单字节符号
如果由两个较短
的符号合并创建
一个较长
的符号,如果较长的符号再之后的增益排序
中处于末尾
就会被其他增益较长的字符串取代
,这也就意味着原先
那两个较短
的字符串也就随之消失
。
从本质上说,如果不考虑单字节,符号只会变长,如果这样更好的话,就永远不可能回到更短的符号。连续注入单字节符号允许重新生长
由于这种太贪婪
的选择而丢失的有价值的长符号。
:::
增益顺序
选择前 255 个符号。这种方法的问题是:选择的符号可能重叠
,因此计算的增益会被高估
。例如,在 URL 数据集中,8 字节符号 http://w 几乎每个字符串都含有,最有希望被选中。但符号 ttp://ww 和 tp://www 看起来同样有希望,将所有三个候选者添加到符号表中是对有限代码数量的浪费,并会对压缩因子产生负面影响。选择最长
的符号不一定能最大化压缩效率 。 参考我们在上文提到的连续单字节注入
.::: hljs-left
(1)迭代语料库,使用当前的符号表动态编码
。 这个阶段计算
符号表的整体质量(压缩因子)
,但也计算每个符号在压缩表示中的出现频率
,以及每个连续符号对
。
(2)利用这些计数,通过选择表观增益最高
的符号来构建一个新的符号表
。
实例
语料库“tumcwitumvldb”上的 4 次迭代。为了使示例易于说明,将最大符号长度限制为 3(而不是 8),最大符号表大小限制为 5(而不是 255)。在每次迭代之后,在顶部显示压缩后的字符串,但为了可读性,不显示代码,而是显示相应的符号。“$”表示转义字节。
:::
临时加倍
,因为符号表最初是空的
,每个符号都必须转义。在图的底部,我们显示了符号表,前 5 位符号基于静态增益
。迭代 1 后,静态增益排名前 5 位的为“um”、“tu”、“wi”,“cw” 和 “mc”。 前两个最上面的符号(“um”,“tu”)出现了两次,因此增益为 4,而后三个符号(“wi”,“cw”和“mc”)只出现一 次,因此增益为 2。注意,符号“mv”,“vl”,“ld”,“db”, “m”,“t”,“u”的增益也为 2,也可以被选取。换句话说,当选择顶部符号时,算法会任意地选取
。
质量稳步提高
。会出现错误
,但这些错误会在下一次迭代中得到修复
。技术优化:
AVX512压缩
第一步,FSST API 压缩一批字符串,字符串被复制到一个由 512 个段组成的临时缓冲区
中,如果需要将分割
长字符串,并添加终止符
。
第二步,首先按反向字符串长度对作业队列数组进行基数排序
——速度很快,只需一次传递——因此首先处理最长的字符串,这有助于负载平衡
。作业可能以不连续的顺序完成,因此由于排序而以不连续的作业顺序开始编码工作,不会使算法(进一步)复杂化。
第三步,AVX512 的优势不是内存访问,而是在压缩内核中利用的并行计算
。 不只是一次性启动 SIMD 内核
来处理 8 个通道中的 8 个字符串(或 24 个通道中的 24 个字符串,3×展开),因为有些字符串会比其他字符串短得多,而有些字符串会比 其他字符串压缩得多。这将意味着在编码工作结束时,许多通道将是空的。因此,缓冲 512 个作业,并在需要时在每次迭代中重新填充车道。退出作业(作业控制寄存器中的 通 道 )使 用compress_store 指 令
, 并 填 充 expand_load 指令
。
· 速度
上表显示了 LZ4 和 FSST 在每个数据集上分别和平均的三个指标的相对性能。
对于几乎所有的数据集,FSST 在压缩因子和压缩速度方面都优于 LZ4。平均而言,除了产生更好的压缩因子 FSST 的压缩速度也提高了 60%。 对于解压速度,FSST 在某些数据集上更快,而 LZ4 在其他数据集上更快——平均速度几乎相同。
· 随机存取
在数据库场景中,通常不存储大文件,而是使用包含大量相对较短字符串的字符串属性或字典。用 LZ4 单 独压缩这些字符串会得到非常差的压缩系数,普通 LZ4 (LZ4 行)不能合理地处理短字符串—压缩因子低于 1,这意味着数据大小实际上略有增加。LZ4 还可选地支持使用额外的字典,该字典需要与压缩数据一起提 供。使用 zstd 预生成一个适合语料库的字典(LZ4 字典), 在一定程度上提高了压缩因子,但严重影响了压缩速度。
下图是测试结果
· 分文本数据
数据库环境之外,压缩社区经常评估 Silesia 语料库
上的压缩方法,该语料库由 11 个文件组成,其中 4 个 是文本文件(dick- ens, reymont, mr, webster)
,1个是 XML
, 6 个是二进制文件
。FSST 对文本文件的压缩大小平均提高了 10%,但对二进制文件的压缩大小平均降低了 25%。 虽然认为二进制文件与 FSST 无关,但它在大型 XML
和 JSON 文件
上的压缩比
比 LZ4 差 2-2.5 倍,这是相关的。但是,数据库系统不应该将这些组合值存储为简单的字符串,而应该存储为允许查询处理的特殊类型。例如,Snowflake
识别 JSON 列中的结构,并在内部将
每个经常出现的 JSON 属性存储在单独的内部列中。
FSST 压缩算法经过多次迭代才达到当前的设计。上表 显示了 7 种变体的压缩因子(CF)、符号表构建成本(CS)和字 符串编码速度(SE)
第一个设计基于后缀数组,压缩因子达到1.97,但符号表的构造需要 74.3 cy- cles/字节,编码需要 160 cycles/字节。
目前的 AVX512 版本(图中的变体 7)在表构建方面快了 90 倍,快了40倍 用于编码比第一个版本-同时提供更高的压缩因子。
最终的版本也比最初的 FSST 版本(变体 4)快得多,这要归功于损耗完美哈希和 AVX512——尽管不得不牺牲相对于变体 4 大约 6%的空间增益。
尽管需要多次迭代,但符号表的构造时间只占编码时间的一小部分。 优化构造需要将迭代次数从 10 次减少到 5 次,构建一个示例(每次迭代都会增长),并缩小计数器的内存占用。
sudo apt update
sudo apt install cmake
可以看到 cmake 在之前已经安装过了,并且版本是 3.18.4 :
sudo apt install zstd* lz4* libzstd* liblz4* # 同 cmake 的安装
完成后,可以在 /usr/lib/x86_64-linux-gnu/ 下看到相关文件已生成:
此外,还需要建立到 /usr/lib/ 的软链接,避免后续链接时出现找不到缺省目录的问题:
# 注意,下方诸如 '1.4.8' '1.8.3' 一类的版本号需要根据实际状况进行相应地替换
cd /usr***/lib/x86_64-linux-gnu/
echo '../libzstd.so ../libzstd.so.1 ../libzstd.so.1.4.8' | sudo xargs -n 1 ln -s libzstd.so.1.4.8
echo '../liblz4.so ../liblz4.so.1 ../liblz4.so.1.8.3' | sudo xargs -n 1 ln -s liblz4.so.1.8.3
编译构建
cd -
cmake ./
make -j8 && make binary
100% 完成后,说明编译已成功,查看所在目录,可以看到 fsst 的二进制程序已生成:
vim ~/.bashrc
export PATH=/home/yanxu/ELT.ZIP/fsst:$PATH # 在尾行添加
:wq # 保存退出
已经可以正常使用,输入 fsst 即可查看说明:
评估测试
自动化测试
cd paper/
chmod +x *.sh
results 目录中已存放有作者测试过的结果,但我们同样可以在自己机器上再进行一遍测试,执行如下命令:
make experiments
花费时间会较长,耐心等待即可,这里举出作者的其中一项示例:
最左侧的一列是各式各样的字符集,另外三个框框分别表示压缩比、压缩速度、解压速度,其中,左侧是 LZ4、右侧是 FSST。不难看出,压缩比方面,FSST 仅在 urls 上较 LZ4 弱了一点;压缩速度方面,LZ4 仅在 hex 上取得了微弱的优势;而解压速度方面,则是二者互有胜负,可以视作忽略不计。
手动测试
更多回帖