zlib v1.2.12优化补丁仓介绍
项目介绍
zlib是通用的DEFLATE压缩库,提供zlib、gzip和raw DEFLATE数据格式支持。本交付件以开源zlib v1.2.12 tag为基线,提供单独优化补丁文件。该优化主要面向Linux AArch64平台,尤其是鲲鹏处理器。它保持了开源zlib对外API、ABI主版本和压缩数据格式兼容,通过ARM NEON/SVE、CRC指令、宽字读写、Huffman快速表和压缩匹配算法调整,降低压缩、解压热路径的指令与内存访问开销。
优化原理
压缩路径
- AArch64下使用CRC32指令计算4字节哈希,减少逐字节滚动哈希开销;其他架构保留通用实现。
- 最长匹配比较改为按机器字批量异或,并通过
ctz快速定位首个不同字节,减少逐字节比较和分支。 - 压缩级别1~3使用精简的快速匹配路径;级别4~6使用新的
deflate_medium延迟匹配流程;高级别调整哈希链搜索参数,控制搜索成本。 - AArch64滑动窗口哈希表更新使用NEON或SVE饱和减法批量处理。
- 最小优化匹配长度使用4字节,提高CRC哈希和宽字比较的利用率。该策略可能使压缩输出字节序列和压缩率与原版略有差异,但输出仍是标准DEFLATE数据。
比特流编码
- deflate位缓冲区从16位扩展到64位,减少频繁写出短比特段的次数。
- 长度码和距离码使用预计算组合表,将码字、extra bits和基础值合并处理。
- 小端平台使用16、32、64位批量写入pending buffer,降低字节级写入开销。
解压路径
- 当输入和输出缓冲区足够大时,构建更宽的Huffman快速解码表,将符号、码长、基础值和extra bits信息合并到表项。
- 快速循环使用64位小端输入读取,降低补充bit buffer的频率。
- NEON/SVE路径使用向量化chunk copy处理普通和重叠匹配复制,提升inflate输出阶段吞吐。
- 输入或输出空间不足时自动回退到原有解码表和状态机路径,保证流式、小缓冲区场景的正确性。
Adler-32与平台选择
- 支持dot-product的AArch64 CPU使用NEON DOT指令计算Adler-32。
- 使用
--sve配置时启用SVE Adler-32、滑动哈希和解压复制路径。 - 默认AArch64构建会运行
check_cpu_feature_dot.sh探测DOT指令;不支持DOT时仍使用ARMv8 CRC和NEON解压路径。
环境要求
- 推荐环境:Linux AArch64、鲲鹏处理器、GCC或兼容编译器。
- 默认模式需要ARMv8 CRC和NEON;DOT指令会在构建时探测。
- SVE模式要求编译器和运行CPU均支持SVE。
- 需要
tar、make,以及git或patch。 - 建议在目标AArch64机器上原生编译。当前
configure的自动架构选择依赖本机uname结果,不适合作为通用交叉编译配置。 - 补丁文件中的构建加固和链接参数主要面向Linux,MacOS、Windows及其他Unix平台不属于本交付件的验证范围。
快速入门
自动应用补丁
自动应用补丁步骤
获取交付件,在交付件目录下执行以下命令运行build.sh脚本文件。
chmod +x build.sh
./build.shbuild.sh脚本会完成以下操作,脚本结束时会输出源码构建目录和安装目录相关信息。
- 在
tmp/下创建独立构建目录。 - 解压zlib源码包
zlib-1.2.12.tar.gz。 - 校验并应用
zlib-optimizs-v1.2.12.patch文件。 - 执行
configure和并行编译。 - 默认执行
make test。 - 默认安装到本次构建目录的
install/子目录。
SVE构建
仅在目标处理器和编译器确认支持SVE时执行以下命令进行SVE构建。SVE是编译期选择,不包含运行时自动降级。SVE版本不能部署到不支持SVE的处理器。
./build.sh --sve常用构建参数
JOBS=16 ./build.sh
RUN_TESTS=0 ./build.sh
RUN_INSTALL=0 ./build.sh
BUILD_DIR=tmp/zlib-opt-build ./build.sh
INSTALL_PREFIX=/opt/zlib-1.2.12-opt ./build.shBUILD_DIR指定的目录不能预先存在。未指定时,脚本会在tmp/下创建随机命名目录。
手动应用补丁
该补丁文件需要应用到干净的zlib v1.2.12源码。其他zlib版本或已经修改过的源码可能产生冲突,不建议强制应用。
手动应用补充步骤
mkdir -p tmp/manual
tar -xzf zlib-1.2.12.tar.gz -C tmp/manual --strip-components=1
cd tmp/manual
git apply --check --whitespace=nowarn ../../zlib-optimizs-v1.2.12.patch
git apply --whitespace=nowarn ../../zlib-optimizs-v1.2.12.patch
./configure --prefix="$PWD/install"
make -j"$(nproc)"
make test
make install若没有安装Git则可使用以下命令进行补丁应用。
patch -p1 < ../../zlib-optimizs-v1.2.12.patch使用优化库
安装后的头文件和库位于脚本运行完成后输出的安装目录中。
动态链接程序可通过安装路径或LD_LIBRARY_PATH选择优化库。
export LD_LIBRARY_PATH=/path/to/install/lib:${LD_LIBRARY_PATH:-}
ldd /path/to/application | grep libz也可以在构建上层软件时显式指定。
CPPFLAGS="-I/path/to/install/include" \
LDFLAGS="-L/path/to/install/lib" \
./configurezlib接口使用方式与开源v1.2.12保持一致。替换系统libz.so前,应先在隔离环境验证依赖程序,不建议直接覆盖操作系统自带库。
验证建议
- 保留
make test,确认静态库和共享库的example、minigzip测试通过。 - 使用真实业务数据分别测试压缩吞吐、解压吞吐、压缩率和CPU占用。
- 使用原版zlib解压优化版生成的数据,并使用优化版解压原版数据,验证双向格式兼容。
- 使用
ldd确认业务程序实际加载的是优化后的libz.so.1。 - 在SVE和非SVE机器分别构建和部署,避免将SVE二进制复制到不支持SVE的环境。
使用约束
- 性能收益与数据分布、压缩级别、输入块大小、编译器和CPU微架构有关,应以业务压测结果为准。
- 压缩匹配启发式和链长参数已调整,压缩率可能与原版v1.2.12略有差异。
- 本交付件基于历史版本v1.2.12。用于生产环境前,需要结合业务安全要求评估上游后续修复和版本维护策略。
- 优化源码包含其文件中声明的zlib、ARM/Chromium BSD、MIT及Huawei版权与许可说明,分发时应保留原有声明。