zlib-rs 中的 SIMD(第二部分):compare256 - 博客 - 第二轮

H1:“SIMD in zlib-rs 系列之比较 256 函数优化”

  • 部分 1 内容:通过一些调整,自动向量化可为某些问题生成最优代码,但并非总是有效,此次将探讨编译器目前无法有效利用现代 CPU SIMD 能力的问题。
  • 问题阐述compare256函数用于比较两个[u8; 256]值,从左开始计算元素匹配的位置,直到出现不匹配,此函数是 zlib-rs 压缩算法的核心。该函数生成的汇编代码未进行自动向量化,编译器展开循环 4 次,每次处理 4 字节,但可通过显式 SIMD 实现更好效果。
  • 实现思路:以假设的 32 位 SIMD 向量为例,将输入按 4 个 8 位元素分组加载到向量寄存器,进行按位相等操作,生成掩码向量,再将其转换为整数,最后使用.trailing_ones方法计算匹配元素的数量。
  • 实际实现:在现代 CPU 的 128 位 SIMD 寄存器上实现compare256函数,使用特定的导入和指令,如__m128i_mm_loadu_si128_mm_cmpeq_epi8_mm_movemask_epi8等,循环展开 16 次处理整个 256 字节输入,汇编代码较长。观察到一些指令的优化处理,如_mm_loadu_si128被优化为movdqu等。
  • 基准测试:手动 SIMD 实现效果显著,在某些简单输入下比旧代码快约一个数量级,给出了具体的基准测试设置和结果。
  • 结论:展示了自定义 SIMD 实现优于编译器的基本但有效的例子,其他指令集的示例可在[compare256.rs]中找到,下一次将探讨如何为实际运行的 CPU 高效选择合适的 SIMD 解决方案。
阅读 10
0 条评论