HN 日本語サマリー

← 一覧へ戻る
プログラミング

Fearless SIMD v1.0

Fearless SIMD v1.0 (linebender.org)

94 pointsby verdagon16 コメント

要約

Rust向けのSIMD(Single Instruction, Multiple Data)ライブラリであるFearless SIMDがバージョン1.0に到達しました。このライブラリは、SIMD処理における`unsafe`コードの必要性を排除し、パフォーマンスと安全性を両立させることを目指しています。ポータブルな抽象化、プラットフォーム固有のイントリンシックへの安全なアクセス、そして使いやすいマクロを提供します。

全文翻訳

Fearless SIMD v1.0 が登場しました Shnatsel, 2026年9月22日 fearless_simd は SIMD から unsafe を取り除きます。最初のプロトタイプから8年を経て、長い道のりを歩んできました。オートベクター化とマルチバージョン化だけが必要な場合でも、本格的なポータブル SIMD 抽象化が必要な場合でも、あるいはイントリンシックへの安全なアクセスだけが必要な場合でも、Fearless SIMD はきっと役に立つと確信しています。変更履歴を言い換える代わりに、この機会に Fearless SIMD の目標、それをどのように達成しているか、そして他の SIMD 抽象化と何が違うのかを振り返りたいと思います。パフォーマンス ポータブル SIMD 抽象化に対する一般的な批判は、パフォーマンスが十分ではないというものです。そのため、Fearless SIMD が決してあなたの足を引っ張らないように、多大な努力を払ってきました。例えば、スワズルや浮動小数点数の最大値のように、プラットフォームごとにエッジケースの動作が異なる操作に対するポータブルな抽象化を実装する際には、すべてのプラットフォームで同じになる正確なバリアントと、エッジケースが発生しないと予想される場合に使えるプラットフォーム依存の結果を返す高速なバリアントの両方を提供しています。また、SIMD アルゴリズムをハードウェアのネイティブベクトルサイズで表現しやすくしており、コードがどこで実行されても常にハードウェアを最大限に活用できるようにしています。固定ベクトルサイズのサポートも、それらを必要とするアルゴリズムのために提供しています。ポータブル SIMD 操作の実装が最先端であることを保証するためにも多大な努力を払い、Rust と LLVM の両方に改善を貢献してきました。しかし、ポータブル抽象化でカバーされていない命令が必要な場合や、さらに多くの制御が必要な場合は、パフォーマンスのオーバーヘッドなしにプラットフォームイントリンシックに安全にドロップダウンでき、残りの部分はシンプルでポータブルに保つことができます。イントリンシックへの安全なアクセスのおかげで、パフォーマンスの天井はありません。安全性 他の SIMD 抽象化のソースコードを見ると、`unsafe` コードでいっぱいであることがわかります。`rg unsafe` のようなものでは、数千もの `unsafe` ブロックが見つかるでしょう。しかし、Fearless SIMD にはありません!このクレートは、アドホックな `unsafe` コードを必要としないように慎重に設計されています。パズルの1つは `kernel!` マクロです。これはコンパイラの `target_feature` v1.1 に依存して、ほとんどの SIMD イントリンシックを `unsafe` なしで呼び出します。設計については、以前のブログ記事で詳細に説明しましたので、さらに詳しく知りたい場合はそちらをご覧ください。これにより、アドホックな `unsafe` のほとんどは排除されますが、生のポインタを操作する SIMD のロード/ストア操作はカバーされません。そこで、`bytemuck` や `zerocopy` のようなクレートに触発された、安全な `transmute` モジュールが登場します。`_mm_loadu_epi32` のような SIMD イントリンシックは特別に見えるかもしれませんが、実際には舞台裏では通常のロードとストアに変換されます。そのため、単一の再利用可能なラッパーでその機能を完全に再現できます。Rust の型システムの力のおかげで、これらの2つの小さく自己完結したビルディングブロックを監査するだけで済みます。それらがメモリ安全であれば、コードベースの残りの部分もメモリ安全であることが保証されます。ついに、Rust での SIMD は真に恐れを知らぬものになりました。エルゴノミクス 関数マルチバージョン化はトリッキーです。以前のソリューションは、`#[inline(always)]` アノテーションを追加してその意味を理解する必要があるか、すべての関数呼び出しに小さなオーバーヘッドを課していました。後者はほとんどの場合問題ありませんが、非常に小さな関数ではパフォーマンスが低下し、それを回避するためには `#[inline(always)]` を外科的に追加する必要がありました。どちらもリーキーな抽象化であり、舞台裏で何が起こっているのかをまだ考える必要があります!Fearless SIMD v1.0 と同時に、リーキーでない抽象化を提供する `fearless_simd_macros` v0.1 をリリースします。これは `#[simd]` マクロです。これを使えば、舞台裏で何が起こっているのかをまったく考える必要はありません!任意の SIMD 関数に適用すれば、ただ動きます。とはいえ、これはエコシステムにとって大きな一歩ですが、まだ多少のボイラープレートが関わっています。コンパイラによる `Struct Target Features` RFC を通じて `#[simd]` アノテーションを完全に削除するためのサポートを得るか、あるいは将来探求する他のトリックを通じて、それをさらに削減することに意欲的です。そして、プロシージャルマクロが気に入らない場合は、従来の方法も引き続き利用可能ですが、利便性は低くなります。エルゴノミクスは、まだ進化する可能性があると予想される分野です。しかし、これはコアの `fearless_simd` クレートの安定性保証を損なうものではなく、今日 `#[simd]` マクロの有無にかかわらず書かれたコードは、無期限に動作し続けます。安定性 Fearless SIMD はここに留まります。v1.0 およびそれ以降のすべてのバージョンに対して3年間のセキュリティアップデートを提供します。未来を見ることはできませんが、f16 型のような近い将来の Rust 機能と、SVE や RISC-V ベクトル拡張のような長期的な機能(これらのハードウェア拡張が関連性を持つようになれば)の両方を、API を破壊する変更なしにサポートするための実行可能なパスがあります。std::simd との関係 std::simd が安定化されることを望んでいますが、それは Fearless SIMD を時代遅れにするものではありません。Rust 標準ライブラリは、絶対に必要不可欠な部分のみを実装しており、残りの部分(例: マルチバージョン化、ハードウェア幅ベクトル)はエコシステムクレートに任されています。fearless_simd は、安定版 Rust で動作する std::simd の同等物を含んでいますが、それはより大きな全体の一部にすぎません。std::simd が安定化されたら、カスタムコードの多くを削除し、あらゆる種類のマイナーなプラットフォームのサポートを得るために、Fearless SIMD をそれに移植します。しかし、fearless_simd のようなエコシステムクレートの必要性は残ります。採用 クレートがどれほど優れていても、誰も使っていなければ意味がありません。Fearless SIMD はすでに30以上の他のクレートに直接依存されており、1000以上のクレートに間接的に依存されています!すでに Rust エコシステムの相当な部分を支えており、v1.0 がさらにそれを押し進めることを願っています。プロジェクトで Fearless SIMD を使用したい場合は、ドキュメントと例を確認し、Zulip で質問を遠慮なくお寄せください!