资讯动态

WiredTiger 在 z/Architecture 上的硬件加速 CRC-32 实现:深入解读 crc32-s390x 与向量伽罗华域乘法(VGFM)

发布时间:2026/9/17 4:52:09 来源:尧图企业网站定制
WiredTiger 在 z/Architecture 上的硬件加速 CRC-32 实现深入解读 crc32-s390x 与向量伽罗华域乘法VGFM【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo导读本文围绕 MongoDB 所内嵌的 WiredTiger 存储引擎中位于 src/third_party/wiredtiger/src/checksum/zseries/README.md 的 CRC-32 加速库展开。该库利用 IBM z13 及之后处理器引入的Vector Galois Field MultiplyVGFM / VGFMA向量伽罗华域乘法指令族在 Linux on z Systemss390x上把 CRC-32 与 CRC-32C 校验计算提速约 70 倍。读完本文你将掌握这套库提供的函数接口与端序变体、其快速上手方式、四种正确性测试的用法、与 slicing-by-8 基准的实测对比以及它在 WiredTiger 中如何通过运行时硬件探测自动选择硬件或软件实现并配套阅读完整的 C 与汇编源码。一、背景为什么要在 z/Architecture 上用向量指令算 CRCCRC循环冗余校验是存储引擎保证数据完整性的核心手段WiredTiger 的每个 block 都带有 CRC-32C 校验值计算频率极高因此其性能直接影响吞吐。传统的纯软件实现如 slicing-by-8 查表法虽然高效但在 IBM z 系列z13 及之后上硬件提供了更快的路径z/Architecture 的Vector Extension Facility提供了两条在二进制伽罗华域GF(2)上执行乘法的指令VGFMVector Galois Field Multiply与VGFMAVector Galois Field Multiply and Accumulate。两条指令都支持不同的元素尺寸字节、半字、字、双字。对于 32 位 CRC 计算本实现全程使用**双字doubleword**元素。CRC 的本质正是 GF(2) 多项式除法取余因此把数据块折叠fold与最终归约reduce映射为向量乘法是自然的加速思路。README 明确说明该库就是“利用 z13 引入的向量伽罗华域乘法指令族加速 CRC32 计算”的函数库。二、库速览目录结构与可提供的算法zseries/目录下的源码文件如下文件作用crc32-s390x.h公开函数原型声明crc32-s390x.c纯 C 软件实现、硬件/软件分派封装及 WiredTiger 集成入口crc32le-vx.S基于 VGFM/VGFMA 的汇编核心vx-insn.h为旧版 binutils 2.26生成向量指令字节码的汇编宏slicing-consts.h大端系统使用的 slicing-by-8 查表常量LICENSE.TXTGPLv2 或 Apache 2.0 双许可声明该库提供两类 CRC 算法并各自支持可选的**位反射bit reflection**变体即 README 所说的*_le版本从最低有效位开始处理即小端语义CRC-32IEEE 802.3生成多项式P(x) 0x04C11DB7反射多项式P(x) 0xEDB88320CRC-32CCastagnoli生成多项式P(x) 0x1EDC6F41反射多项式P(x) 0x82F63B78。两个多项式的定义可以直接在 crc32le-vx.S 头部的注释中找到它们在反射域bit-reflected domain中参与归约常数的预计算。三、快速开始make 生成静态库README 的 Quick start 部分给出了最直接的用法执行make即可生成静态库libcrc32_s390x.a。该库对外提供的函数用于计算 CRC-32IEEE 802.3与 CRC-32CCastagnoli并带有可选的位反射通过*_le后缀函数实现。函数原型声明在crc32-s390x.h中示例程序crc32-cli.c演示了库的使用方式。需要说明的是README 描述的make、crc32-cli.c示例以及后文提到的_bench/_test可执行程序属于该库独立发行版的一部分在当前仓库中该库以内嵌源码形式存在于 WiredTiger 中目录下保留了 crc32-s390x.c 等源码文件通过 WiredTiger 的构建系统编译集成而独立发行包中的 CLI 与基准工具不在本目录中。四、函数接口与 WiredTiger 的集成方式4.1 头文件中的公开接口crc32-s390x.h 声明了两类函数/* Portable implementations of CRC-32 (IEEE and Castagnoli), both big-endian and little-endian variants. */ unsigned int __wt_crc32c_le(unsigned int, const unsigned char *, size_t); /* Hardware-accelerated versions of the above. It is up to the caller to detect the availability of vector facility and kernel support. */ unsigned int __wt_crc32c_le_vx(unsigned int, const unsigned char *, size_t);__wt_crc32c_le可移植的纯 C 实现逐字节查表使用 slicing-consts.h 中的crc32ctable_le可运行在任何平台上__wt_crc32c_le_vx硬件加速版本但头文件注释明确提醒——由调用方负责探测向量设施与内核支持的可用性这正是 WiredTiger 集成层所做的工作。4.2 DEFINE_CRC32_VX 宏对齐与分派策略crc32-s390x.c 中通过DEFINE_CRC32_VX宏生成了主入口__wt_crc32c_le_vx其内部策略非常清晰源码第 55~83 行#define VX_MIN_LEN 64 #define VX_ALIGNMENT 16UL #define VX_ALIGN_MASK (VX_ALIGNMENT - 1)前对齐pre-align若数据指针未按 16 字节VX_ALIGNMENT对齐先用软件实现处理头部prealign字节把指针推进到对齐边界——这是为了让后续的VECTOR LOAD MULTIPLE指令获得更好的取数性能短数据回退若剩余长度不足VX_MIN_LEN64 字节整体交给软件实现处理避免向量路径的开销得不偿失主体折叠对齐且足够长的部分按 16 字节整块交给汇编函数__wt_crc32c_le_vgfm_16尾部收尾剩余不足 16 字节的尾巴再次由软件实现处理保证任意长度、任意对齐的数据都能得到正确结果。4.3 运行时硬件探测wiredtiger_crc32c_func()WiredTiger 的集成入口同样在 crc32-s390x.c 中核心是wiredtiger_crc32c_func()caps getauxval(AT_HWCAP); if (caps HWCAP_S390_VX) return (crc32c_func __checksum_hw); else return (crc32c_func __wt_checksum_sw);要点通过getauxval(AT_HWCAP)读取内核暴露的硬件能力位HWCAP_S390_VX表示 CPU 支持向量扩展。代码还专门处理了 RHEL 7 的兼容问题——其内核已支持该能力但 libc 头文件未定义该常量因此代码在#ifndef HWCAP_S390_VX时手动补充定义#define HWCAP_S390_VX 2048探测到向量设施时返回__checksum_hw其内部为~__wt_crc32c_le_vx(0xffffffff, chunk, len)即标准的 CRC-32C 初始化/取反约定否则回退到 WiredTiger 的纯软件校验函数__wt_checksum_sw函数指针带有静态缓存crc32c_func首次探测后即固定避免每个请求都重复调用慢速的硬件能力查询整个文件以#if defined(__linux__) !defined(HAVE_NO_CRC32_HARDWARE)包裹可通过HAVE_NO_CRC32_HARDWARE编译选项显式禁用硬件路径。另外wiredtiger_crc32c_with_seed_func()用于分块chunkedCRC 计算由于大端平台上不支持对多块的硬件 CRC 累加该函数统一回退到带种子seed的软件包装函数__crc32c_le_wrapper。4.4 构建集成WiredTiger 的构建系统在 cmake/platform/arch/s390x.cmake 中做了专门处理# z/Architecture builds compile src/checksum/zseries/crc32le-vx.S, so the ASM # language must be enabled. enable_language(ASM)即 z/Architecture 构建需要编译crc32le-vx.S汇编源因此必须启用 CMake 的 ASM 语言支持。同目录下 WiredTiger 还提供了 arm64、power8、riscv64、x86 等架构的对应加速实现见 src/third_party/wiredtiger/src/checksum 目录zseries 是其中的 s390x 专属实现。五、正确性验证与 Rocksoft Model 对拍README 的 Testing 部分规定硬件加速实现的正确性通过与纯软件的 Rocksoft Model CRC 算法对拍来验证。共有四种测试变体每种针对一种 CRC 类型在随机数据、随机对齐、随机缓冲区大小的条件下无限循环运行./crc32_be_test ./crc32_le_test ./crc32c_be_test ./crc32c_le_test一旦硬件加速算法与 Rocksoft Model 产生任何不同的结果测试程序会打印错误信息用于定位。除了发行版自带的这四个对拍程序WiredTiger 的单元测试 test/catch2/misc_tests/test_crc32.cpp 也用已知向量做了固化的回归验证对 4 字节全零输入{0x00,0x00,0x00,0x00}得到0x48674bc7对 4 字节全一输入{0xff,0xff,0xff,0xff}得到0xffffffff对一段重复拼接的长字符串得到0x47a00ee5并验证了用crc32c_with_seed分块累加的结果与一次性计算一致空指针/空串/零长度输入一律返回 0带种子接口在零长度下返回原种子。这些用例覆盖了空输入、边界值、长数据与分块计算等关键场景与 README 的“随机数据 随机对齐 随机长度”对拍互为补充。六、性能与 slicing-by-8 的 70 倍差距README 的 Performance 部分给出了一组可复现的基准数据。测试方式是对32kB 数据执行 500000 次 CRC 计算将硬件加速实现crc32_vx_bench与 slicing-by-8 软件算法crc32_sw_bench对比$ time ./crc32_sw_bench 32768 500000 CRC: a98177aa real 0m21.862s user 0m21.859s sys 0m0.002s $ time ./crc32_vx_bench 32768 500000 CRC: a98177aa real 0m0.323s user 0m0.323s sys 0m0.000s两点值得注意两个基准程序输出了相同的 CRC 值a98177aa这本身就是一次直观的一致性印证软件版本耗时约 21.86 秒硬件版本约 0.323 秒约 70 倍的加速。这是 z13 向量伽罗华域乘法指令在典型 32kB 块校验场景下的实测数据来源于 README 记录的测量结果。需要说明的是该基准是 README 在特定机器上的一次性测量记录实际加速比会随 CPU 型号、数据长度、内存带宽等条件变化_bench程序属于库的独立发行版未包含在当前仓库目录中。七、汇编核心原理折叠与 Barret 归约理解 70 倍加速的来源需要看懂 crc32le-vx.S 的实现思路源码注释非常详尽7.1 归约常数常量块.Lconstants_CRC_32_LE与.Lconstants_CRC_32C_LE分别存放两套预计算常数BE→LE 字节交换掩码、折叠常数R1~R5、Barret 归约常数u以及反射多项式P(x) 1。R1~R5 按以下定义预计算注释中给出R1 [(x4*12832 mod P(x) 32)] 1 R2 [(x4*128-32 mod P(x) 32)] 1 R3 [(x12832 mod P(x) 32)] 1 R4 [(x128-32 mod P(x) 32)] 1 R5 [(x64 mod P(x) 32)] 1 R6 [(x32 mod P(x) 32)] 1其中u是floor(x^64 / P(x))的位反转bit reversal。P(x)为正常域多项式P(x)为反射域多项式。7.2 主循环与折叠汇编入口__wt_crc32c_le_vgfm_16的调用约定为%r2初始 CRC 值通常为~0与最终返回值%r3输入缓冲区指针若位于双字边界可获得更佳性能%r4缓冲区长度必须不小于 64 字节这是 C 层VX_MIN_LEN保证的前提。算法主流程VLM一次加载 64 字节到向量寄存器V1..V4VPERM按掩码做 BE→LE 字节反射VGFMAG %v1,CONST_R2R1,%v1,%v5等四条指令把当前 64 字节块与下一块按 R2/R1 常数做 GF(2) 乘法并累加折叠循环处理直到剩余不足 64 字节剩余 16~64 字节用VGFMAG以 R4/R3 常数继续折叠最终 32 位归约先用 R5 做一次 32 位折叠再执行Barret 归约源码注释给出三步算法1. T1(x) floor( R(x) / x^32 ) GF2MUL u 2. T2(x) floor( T1(x) / x^32 ) GF2MUL P(x) 3. C(x) R(x) XOR T2(x) mod x^32最后VLGVF把结果字从向量寄存器取回%r2返回。整个过程64 字节主循环 16 字节循环 最终归约只依赖VGFM/VGFMA及少量辅助向量指令这正是性能远超逐字节/逐 8 字节查表法的根本原因。7.3 旧汇编器兼容层 vx-insn.hvx-insn.h 是一组 GAS 宏用于为仅支持 binutils 2.26 的向量指令手工生成.byte/.word编码使得代码在更老的汇编器上也能编译。它实现了从VZERO、VLVGF、VLM/VSTM、VPERM、VUPLLF、VSRLB到VGFM/VGFMA的完整指令封装并通过RXB宏计算指令中向量寄存器高位16~31 号寄存器的 RXB 扩展位。文件头部定义了统一的函数入口宏WT_CRC32_ENTRYcrc32le-vx.S中的__wt_crc32c_le_vgfm_16即由此生成并在.note.GNU-stack节中声明栈不可执行。八、总结zseries目录下的 crc32-s390x 库是 WiredTiger 在 IBM z 平台上数据完整性校验的关键加速组件其核心价值可以归纳为三点算法正确硬件路径VGFM 折叠 Barret 归约与软件路径查表法在DEFINE_CRC32_VX宏中无缝衔接任意对齐、任意长度输入均正确并有 Rocksoft Model 对拍与 test_crc32.cpp 已知向量双重验证。运行时自适应通过getauxval(AT_HWCAP)检测HWCAP_S390_VX在有向量设施时自动启用硬件加速否则静默回退软件实现且结果可复现README 基准中硬件与软件输出相同 CRC 值。性能显著README 记录的基准中500000 次 32kB 数据 CRC 计算从约 21.86 秒降至约 0.323 秒约 70 倍加速。对于希望进一步深入源码的读者推荐按以下顺序阅读先看 crc32-s390x.h 的接口再读 crc32-s390x.c 的宏分派与硬件探测逻辑最后对照 crc32le-vx.S 的注释理解折叠与 Barret 归约细节必要时参考 vx-insn.h 的指令编码宏。【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价