
LZ4 v1.11.0 发布:压缩库内置多线程压缩,小数据速度提升
来源标题:LZ4 v1.11.0: multithreading in the library, speed gains for small data
LZ4 v1.11.0 发布,首次将多线程压缩直接集成进 liblz4 库。该版本包含自 v1.10.0 以来的 850 多个提交,显著提升了小数据(尤其是使用字典时)的压缩速度,并修复大量边界场景问题,同时保持二进制兼容。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
代码 Issues5 (5) Pull requests2 (2) Discussions Actions Wiki Security and quality Insights 更多项目 发布版本 v1.11.0 LZ4 v1.11.0 最新 最新 比较 选择一个标签进行比较 抱歉,出错了。 筛选 加载中 抱歉,出错了。 哎呀! 加载此页面时出错。请重新加载此页面。 v1.11.0 c72c7c0 此提交在 GitHub.com 上创建,并使用 GitHub 的验证签名进行了签名。 GPG 密钥 ID:B5690EEEBB952194 已验证 了解 vigilant 模式。 LZ4 v1.11.0 是一次重大更新,整合了自 v1.10.0 以来的 850 多个提交。其核心亮点是多线程压缩,现已直接集成到 liblz4 库中。此版本在小数据上的速度也大幅提升,尤其是在使用字典时,并包含大量针对边界场景的修复。liblz4 仍与之前版本保持二进制兼容,建议升级。 v1.10.0 在 lz4 命令行中引入了多线程压缩,但使用 liblz4 的应用程序并未从中受益。从 v1.11.0 开始,多线程成为 lz4frame API 的一部分:只需设置一个新的字段 LZ4F_preferences_t.nbWorkers,就足以在单次或流式模式下使用多线程进行压缩。 速度随工作线程数量呈显著的线性扩展。下表展示了在 AMD EPYC Genoa 服务器上,使用 gcc 11 编译的 LZ4F_compressFrame() 压缩 silesia.tar(202 MB)的情况: 有了足够多的线程,现在有望在最高压缩级别下不到一秒内压缩完 enwik9…… 压缩输出仅取决于数据和压缩参数:它不会随工作线程数量或线程调度而变化,因此结果在不同系统之间是可复现的。 lz4 命令行现在依赖此能力,并且还新增了 --memory 选项,以将多线程压缩控制在内存预算之内。 lz4 命令行也比 v1.10.0 更快。在线程足够多时,它会达到一个上限,该上限由主线程中仍然串行执行的工作决定:主要是帧的内容校验和(XXH32),它基于整个输入计算,此外还有数据的读写。v1.11.0 进一步推高了这一上限。在消费级桌面(Intel Core i7-9700K,8 核,gcc 13)和数据中心服务器(AMD EPYC Genoa,gcc 11)上,以级别 1 压缩 silesia.tar 的实际耗时如下: 在桌面上约 4 个线程即可达到该上限,约为 2.6 GB/s(v1.10.0:约 2.2 GB/s);在服务器上约 8 个线程达到上限,约为 3 GB/s(v1.10.0:约 2.1 GB/s)。在不启用内容校验和(--no-frame-crc)的情况下,v1.11.0 可以持续扩展:桌面上全部 8 核可达约 4.2 GB/s(v1.10.0:约 3.3 GB/s),服务器上 24 个线程可达约 6 GB/s(v1.10.0:最好情况下约 2.7 GB/s)。 请求超过实际需要的线程数也会减少资源浪费:v1.11.0 仅在有待处理任务时才启动工作线程,且线程数不会超过文件的任务数。在 8 核桌面上使用 16 个线程,或使用服务器的全部 166 个线程时,其速度不变,而 v1.10.0 则会变慢。获得最佳性能所需的调优更少。 这些性能提升也延伸到更高的压缩级别,在级别足够高时,只要有足够的线程,同样会达到相应的上限。 动态库默认启用多线程支持。静态库默认仍为单线程,因此无需链接 -pthread:它仍然接受 nbWorkers,并以单线程产生相同的输出。在此版本中,nbWorkers 被标记为「实验性」,以便在提升为稳定状态之前有时间收集反馈。 许多应用程序以小块形式压缩数据,例如数据库页、缓存条目、冷页、网络消息或日志记录。对它们而言,准备每次压缩的开销至关重要。此版本大幅降低了这一开销,尤其是在复用压缩状态或使用字典进行压缩时。 将 silesia.tar 切分为 4 KB 块,使用 64 KB 字典,除特别注明外均为级别 1,AMD EPYC Genoa。速度为 gcc 11 下的结果,改进幅度为 gcc 11 与 clang 22 下的对比: 4 KB 到 16 KB 的块收益最大,随着块增大而减弱,并且取决于编译器: 这些收益印证了小数据的推荐做法:复用状态和上下文,并使用字典。例如,复用的状态会在其表中保留先前压缩的条目,压缩器随后不得不在每一步将它们过滤掉:v1.11.0 改为清除这些条目,从 1 KB 块起就更为高效。 测量的函数:LZ4_resetStream_fast() + LZ4_compress_fast_continue()、LZ4F_compressBegin() / LZ4F_compressUpdate() / LZ4F_compressEnd()(复用上下文)、LZ4_attach_dictionary()、LZ4F_compressBegin_usingCDict()、LZ4_attach_HC_dictionary()、LZ4F_decompress_usingDict()。 LZ4 的运行规模之大,使得即使罕见的边界情况最终也会发生,因此此版本在测试上投入了大量精力。一个新的单元测试套件逐条契约地检查 API 的文档化行为。变异测试——即故意在代码中引入缺陷以验证某些测试能捕获它们——为新增测试找到了额外的覆盖空间。模糊测试现在也覆盖流式帧压缩、lz4file API 和多线程压缩。并且每一项变更都经过 100 多个 CI 任务的验证。 这项工作发现并修复了若干缺陷。其中许多涉及无效参数,例如负数大小、NULL 指针或极端参数,这些情况不再导致崩溃或溢出,贡献者包括 @arthuz-th、@jaypatrickhoward、@louislafosse、@akashdeshmukh-git 和 @rinsuki。少数缺陷可能在罕见的流式场景下产生错误输出,例如解码到最小尺寸的环形缓冲区,或在部分消费后恢复 LZ4_compress_HC_continue_destSize(),由 @freedom-winds 报告。对于环形缓冲区的情况,更新库即可:使用旧头文件编译的应用程序无需重新编译。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。