← 文章 / 开源项目
Hacker News 50分钟前 · 2026-09-25 05:22:13 · 0 阅读

Fearless SIMD v1.0 发布:让 SIMD 编程告别 unsafe

fearless_simd 让 SIMD 编程摆脱了对 unsafe 的依赖。

自 8 年前的最初原型以来,项目已走过漫长的历程。如今我们确信,无论你需要的是自动向量化与多重版本化、完整的可移植 SIMD 抽象,还是仅仅对 intrinsics 的安全访问,Fearless SIMD 都能很好地满足你的需求。

与其复述变更日志,我更想借此机会回顾 Fearless SIMD 的目标、其实现方式,以及它区别于其他 SIMD 抽象库的特色所在。

性能

可移植 SIMD 抽象常被诟病性能不足。为此,我们投入了大量精力,确保 Fearless SIMD 绝不会成为你的性能瓶颈。

例如,在实现那些在不同平台边缘情况下行为不一致的运算(如 swizzles 或浮点数最大值)的可移植抽象时,我们提供了两种变体:一种是在所有平台行为一致的精确变体;另一种是针对预期不会出现边缘情况而返回平台相关结果的高速变体。

我们还简化了基于硬件原生向量大小来表达 SIMD 算法的流程,确保无论代码在哪里运行,都能充分利用硬件优势。对于需要固定向量大小的算法,我们也提供了相应支持。

此外,我们致力于确保可移植 SIMD 运算的实现达到业界领先水平,并将改进反馈至上游——既贡献给了 Rust,也贡献给了 LLVM。

但如果 portable 抽象没覆盖你需要的指令,或者你想要更强的控制力,可以安全地降级到平台 intrinsics——只在需要的代码部分使用,没有任何额外开销,其余部分依旧简洁且可移植。

多亏了可以安全访问 intrinsics,性能上完全不存在天花板。

安全性

翻看任何其他 SIMD 抽象的源码,你会发现里面全是 unsafe 代码。跑一下 rg unsafe,能搜出数千个 unsafe 块。

但 Fearless SIMD 不是这样!这个 crate 经过精心设计,完全不需要临时的 unsafe 代码。

其中一个关键组件是 kernel! 宏,它借助编译器的 target feature v1.1 特性,无需 unsafe 就能调用大多数 SIMD intrinsics。我在之前的一篇博客里详细讲过这个设计,想深入了解可以去看。

这消除了大部分临时 unsafe,但还有操作裸指针的 SIMD load/store 操作没覆盖到。这时候我们的安全 transmute 模块就派上用场了,它借鉴了 bytemuck、zerocopy 这类 crate。

像 _mm_loadu_epi32 这样的 SIMD intrinsics 看起来很特殊,但底层其实就是普通的 load 和 store。所以用一个可复用的单一封装就能完全复刻它们的功能。

得益于 Rust 类型系统的强大能力,我们只需审计这两个小而自洽的构建模块。只要它们是内存安全的,整个代码库的其他部分也就有了内存安全保证。

Rust 中的 SIMD 终于可以真正做到无所畏惧了。

易用性

函数多版本机制实现起来相当棘手。

此前的方案要么 要求添加 #[inline(always)] 注解并理解其影响,要么 给每次函数调用带来少量开销。后者在大多数时候没问题,但在处理极小函数时会拉低性能,而且你仍得手动加上 #[inline(always)] 才能绕开这一限制。

两者本质上都是“泄漏式抽象”——你依然得操心底层到底发生了什么!

伴随着 fearless_simd v1.0 的发布,我们推出了 fearless_simd_macros v0.1。它提供了一个无缝的抽象层:#[simd] 宏。使用它之后,你完全不必再担心底层实现!只需把宏加在任意 SIMD 函数上,即可开箱即用。

当然,虽然这对生态是巨大的进步,但目前仍需 写一些样板代码。我们希望能进一步削减这些冗余,比如通过 Struct Target Features RFC 获得编译器支持,从而彻底去掉 #[simd] 注解;或者在未来探索 其他技巧 来解决这个问题。

如果你不习惯使用过程宏,旧写法仍然可用,只是没那么便捷。

易用性是唯一一个我们预期可能会继续演进的领域。但这并不影响核心 fearless_simd crate 的稳定性承诺,今天用或不用 #[simd] 宏编写的代码都将长期有效。

稳定性

Fearless SIMD 是长期项目。我们将为 v1.0 及所有后续版本提供 3 年的安全更新支持。

尽管我们无法预见未来,但通往同时支持近期 Rust 特性(如 f16 类型)以及长期特性(如 SVE 和 RISC-V 向量扩展)的路径依然清晰。如果这些硬件扩展变得实用,上述目标均可实现,且无需破坏 API 的兼容性。

与 std::simd 的关系

我们非常期待 std::simd 尽快稳定,但它的稳定并不会让 Fearless SIMD 变得过时。

Rust 标准库只实现必须包含其中的部分,其余功能(例如多版本运行、硬件宽度向量等)则交由生态系统中的第三方 crate 处理。

fearless_simd 包含了 std::simd 的等价功能,且能在稳定版 Rust 上运行,但这只是庞大生态系统的一小部分。

一旦 std::simd 稳定,我们将把 Fearless SIMD 移植到该标准接口上,以此删除大量自定义代码,并获得对更多冷门平台的支持。但 fearless_simd 等生态系统 crate 的需求仍将持续存在。

采用情况

如果没有任何人在使用,那么你的 crate 再精妙也无济于事。

Fearless SIMD 目前已被 30 个 crate 直接依赖,另有 1000 多个 crate 间接依赖于它!

它已支撑起 Rust 生态系统中相当比例的工作负载,我们期待 v1.0 能将其影响力进一步拓展。

若你希望在项目中应用 Fearless SIMD,请查阅文档和示例,并欢迎在Zulip 上提问!

原始来源: Hacker News

评论 (0)