stdarch 的主要工作——SIMD 接口的实现
两种接口实现方式
相同点:都是让用户可以用一般函数调用和传参的方式使用 SIMD 接口,其中需要使用编译器和 LLVM
区别:交互方式
第一种:通过 FFI 静态链接的方式,生成特定的函数签名,由编译器将其翻译成正确的 SIMD LLVM IR 并在 LLVM 生成汇编室,根据 IR 终极静态链接填入相应的汇编指令集。
这种方法和 C 中使用的方法比较类似,相对来说比较直接。缺点:需要开发者对 LLVM 有一定的使用经验,而且对 LLVM IR 有严格的使用要求。
由于 Rust 编译器本身会内置部分通用的 SIMD 指令,如加减乘除、位运算、元素重排等等;通过关键 platform 和 intrinsic 进行使用。使用可以有多条这样的指令组合成可以由 LLVM 的自动向量优化机制识别的一些组合接口。
使用用例:
下面是使用 SIMD 计算 0 到 len 中所有整数点的平方根之和
其他配套工具:
- 硬件特性检测 std-dect
- 自动化函数生成工具 stdarch-gen
- 接口验证工具 stdarch-verify
Rust 中 SIMD 多平台适配库
portable-simd 是多架构通用加速库:http://github.com/rust-lang/portable-simd
发展历程:packed_simd –> packed_simd2 –> portable-simd
编译器提供 platform-intrinsics
然后定义了一套 SIMD 数据结构和方法:sum()、reduce() 、select() 和运算符重载
使用示例:
Rust SIMD 的展望
- portable-simd 功能的完善
- 自动向量长度与指令选择
- 指令集扩展
- 新架构支持
- 丰富、场景化的 API 接口
- 自组合 SIMD 函数
其他计算加速技术
其他计算加速技术:迭代器
- 避免越界检测
- 循环展开
- 惰性计算
- 更好的编辑器 pass 优化
其他计算加速技术:并行化
- rayon:一行代码实现并行化缺点:对迭代器类型和被迭代变量的要求较严格
- async/await、tokio 异步计算技术
其他计算加速技术:编译器优化技术
- 内联汇编
- MIR 优化
- 自动向量化
- 计算图
高性能代码重构实践
识别重构关键点定位
- 重构关键点 1:数据存取通过一次性读取多个数据,用以减少缓存次数,提升程序效率。
不仅仅是顺序读取,可以单次读取多数据,使用 vld4q_s32 SIMD ,比每次读取一次数据提高了 16 倍速率。
- 重构关键点 2:非前后依赖型数据计算,使用 vmlaq_s32 计算三个数组元素,获得 4 倍效率。
- 重构关键点 3:特殊场景—— AES 加解密、哈希算法、矩阵乘法、复数运算等都有专门为其开发的 SIMD 指令。可以直接使用。
重构方法
- 指令替换
- SIMD 接口组合
- 计算逻辑拆分
脏污检测算法代码重构案例
实践 1:迭代器的优化
左边的例子中分别要对 res 、resPrev 、resSum 三个数组进行迭代
而右边的代码通过 zip 方法获得了三个数组的联合迭代器,然后使用 for_each 方法进行循环计算,循环内的取值和计算逻辑保持不变的情况下,效率提升了 20% 左右。
实践 2:SIMD 优化
左边是一段连续的三段代码,可以按照顺序分为三个部分,每个部分都对应了 SIMD 优化的方式:
- 红色部分是数组的访问,也就是访存指令,可以使用 SIMD 指令进行加速,一次读取多个数据
- 绿色部分是乘法和加法的计算,可以使用 SIMD 指令的加法和乘法进行接口的替换和组合
- 蓝色部分是条件判断部分,这部分需要使用布尔型向量(包含全 0 或全 1 元素)存储判断条件,这种向量中每个元素的长度和计算数据类型保持一致,然后使用选择指令实现判断分支
实践 3:运算拆分优化
接下来看一段运算拆分优化的例子,左边的代码可以分为三个部分:- 绿色部分包含自乘计算、访存、类型转换,都可以用 SIMD 指令进行加速
- 红色部分属于累加计算,不可以用 SIMD
- 蓝色部分属于向量加计算,也可以用 SIMD 进行计算
虽然这段代码只有简单的 5 行,但我们可以通过这种方式实现了最好的优化效果。
总结
本文介绍了如何通过 Rust 语言计算加速技术突破识别性能瓶颈,我们都看到 Rust 是一门声名渐起的语言,有着高效和安全的特点,然后介绍 Rust 语言中的 SIMD 技术包括其架构设计、专业指令加速库 stdarch 和接口实现和未来展望。
除了 SIMD 指令加速技术,文中还介绍了其他计算加速技术:迭代器、并行化、编辑器优化技术。
最后在以实践中的例子介绍了如何编写高性能代码重构的方法和案例,希望本文的内容能对你有所帮助,谢谢!