
2026/08/11 3:12
GPU 上の Rust SIMD
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
VectorWare は、既存の CPU コードを書き換えずに、Rust の SIMD 抽象化(例:
core::simd)を用いて高パフォーマンスな GPU アプリケーションを実行することを開発者にもたらす技術であり、この分野における世界初です。この画期的な成果は、標準的なスレッディングの概念を NVIDIA GPU ワープロップに直接マッピングし、手書きの PTX と比較して零のオーバヘッドを実現します(例えば、通常の fn main に #![feature(portable_simd)] を付与したソースコードで)。これは、内部の Rust ベースの中間表現(IR)を活用することで可能になっています。システムは要素ごとの算術演算、レーンマスクを生成する比較、それらによる選択操作、およびレーンをまたぐ水平型削減をサポートします。さらに、ワープロンプログラミングのための決定論的なテストを確保し、CPU デバッグツールに匹敵する信頼性を提供する専用参照インタプリタも実装されています。現在では NVIDIA ハードウェア向けに最適化されていますが、アーキテクチャ非依存の IR は、AMD のウェーブフロントおよび Vulkan サブグループ向けにも設計されています。今後の開発では、GPU 向けのスレッド合成や非同期操作の実装、また行列形状の SIMD をテンザコアへの変換(ローリング)が焦点となります。この進展により、業界ユーザーは新たなベクトル型を導入したり膨大なコード書き換えを伴う高コストなアプローチをとらずとも、要素ごとの算術演算と削減を効率的に活用することができます。ただし、制約としては、ベクトル幅の不一致(例:CPU の柔軟な N 対 GPU の固定 32/64 レーン)、およびハードウェアパターンと一致しない跨レーン操作におけるパフォーマンスコストが含まれます。本文
VectorWare のリリース:Rust core::simd
を GPU で活用する新しい時代の到来
core::simdVectorWare は、世界初の GPU ネイティブソフトウェア企業 として新たなマイルストーンを達成しました。Rust の移植可能 SIMD(
core::simd)が GPU でも成功裏に動作することを確認し、開発者が Rust の馴染み深い抽象化を用いて、GPU の全機能を駆使した高機能なアプリケーションを開発することを可能にしました。
本記事では、このリリースの詳細、技術的な実装方法、メリット・デメリットについて解説します。
1. スレッド内の並列性(Parallelism below the thread)
従来の GPU プログラミングでは、Rust のスレッドを GPU の「ワープロム(Warp)」にマッピングすることで多数の並列処理が可能になっていましたが、ワープロム内部のスレッド(またはレーン)の並列性までは活用できませんでした。
SIMD とは何か?
CPU においてスレッド内の並列性を抽象化する仕組みが SIMD です。
- 動作原理: 1 つの命令で複数のデータ要素に対して同時に操作を行います。
- 具体例: スカラコードで 2 つの数値を加算する代わりに、SIMD add は「8 つの f32 値からなるベクトル」を受け取り、一度に 8 つの和を生成します。
この並列性は、OS がスケジューリングを行うレベルより下位のスレッド内部で行われます。
CPU スレッド ├── SIMD 演算 │ ├── チェーン 0 │ ├── チェーン 1 │ ├── チェーン 2 │ └── … (SIMD チェーン)
同様に、GPU のワープロムも内部に複数のチェーンを持ちます。
GPU スレッド ≒ ワープロム ├── SIMD 演算 │ ├── チェーン 0 │ ├── チェーン 1 │ ├── チェーン 2 │ └── … (ワープロム チェーン)
2. Rust の移植可能 SIMD(Portable SIMD)
歴史的には、Rust で SIMD を記述するにはアーキテクチャ固有のベンダーイントリンシックに頼る必要がありましたが、
はこれを抽象化しました。core::simd
特徴
- 単一の汎用型:
という型が提供され、T 型の N 個の要素からなるベクトルを表現します。Simd<T, N> - 記述の簡便さ: 算術演算や比較操作などは一度だけ記述し、コンパイラがターゲット CPU の命令へと降下させます。
- GPU 対応の利点:
はcore::simd
ライブラリに含まれていないため、GPU 向けに持ってきたstd
サポートさえ不要という軽量な利点があります。std
VectorWare では、GPU も移植可能 SIMD がターゲットとするベクトルハードウェアの一例に過ぎないと捉えています。
動作比較
SIMD の定義は「1 つの命令が多数のデータ要素に対して操作を行う」ことですが、SIMT(Single Instruction, Multiple Threads)モデルにおいてもこの定義を満たします。
CPU の例
let a: Simd<i16, 32> = [1, 1, 1, ..., 1]; let b: Simd<i16, 32> = [2, 2, 2, ..., 2]; let c = a + b; // コンパイル結果:vpaddw %zmm2, %zmm1, %zmm0
GPU の例
同じソースコードですが、コンパイル結果は GPU 向けの命令に変換されます。
let a: Simd<i16, 32> = [1, 1, 1, ..., 1]; let b: Simd<i16, 32> = [2, 2, 2, ..., 2]; let c = a + b; // コンパイル結果:add.s16 %rs3, %rs1, %rs2
このマッピングにより、CPU スレッドと GPU ワープロムが同じ役割(チェーンを駆動する)を果たすことが完成しました。
3. 世界初の「core::simd on the GPU」
core::simd のコードはリスト表記であり、視覚的に CPU との違いが見えにくいですが、ラップトップ上で動作する x86-64 SIMD コードをそのまま GPU でコンパイル可能にしました。ソースコードの変更は一切不要です。
以下のコードは、要素単位の演算、比較マスクによる選択、合計などの中核機能を備えています。
#![feature(portable_simd)] use core::simd::cmp::SimdPartialOrd; use core::simd::num::SimdFloat; use core::simd::{Select, Simd}; // 移植可能 SIMD:ターゲットに応じて x86-64、Arm、またはスカラコードへと降下します。 fn relu_dot(a: Simd<f32, 32>, b: Simd<f32, 32>) -> f32 { // 要素単位の乗算:一度に 32 つの積が計算されます。 let products = a * b; // チェイン単位の比較はマスクを生成し、各チェインに対応する論理値 1 つずつを持ちます。 let positive = products.simd_gt(Simd::splat(0.0)); // 陽の積を残し、残りはゼロに置換します。 let clamped = positive.select(products, Simd::splat(0.0)); // 全てのチェインを横断して合計を単一のスカラ値へ減少させます。 clamped.reduce_sum() } fn main() { // 普通のリストで構築された、幅 32 の 2 つのベクトル。 let a = Simd::<f32, 32>::splat(2.0); let b = Simd::<f32, 32>::from_array(std::array::from_fn(|i| i as f32 - 16.0)); // 要素単位の演算、比較マスクによる選択、そして減少: // いずれも普通のリストで記述された移植可能 SIMD で、いずれも GPU 上で動作します。 let result = relu_dot(a, b); // GPU から印刷されます(我々の std サポートを使用)。 println!("relu_dot = {result}"); }
エントリーポイント:
fn main に GPU 固有のアノテーションは含まれていません。VectorWare のツールチェーンがこれを GPU カーネルとしてコンパイルし、結果をデバイス上から印刷します。
4. 実装方法
このマッピングは、「ワープロムはチェイン個々にアドレス可能であるベクトルユニットである」という洞察に基づいています。
対応可能な操作
- 要素単位の演算: 加算、乗算、比較などは
に対する普通のリストのトレイト実装から得られ、GPU はこれらをネイティブに実行します。Simd - SIMD 合計:
やreduce_sum
は GPU のワープロムシャッフル命令を利用して値を統合し、同じスカラ結果を生成します。reduce_max - チェイン横断のシャッフル: シフトや回転などは、GPU のチェインがデータを交換するのに優れたワープロムシャッフル原語へと直接マッピングされます。
- SIMD マスク:
はすべてのワープロムチェインで選択を実行し、Mask::select
やany
などの横断クエリは GPU の投票(vote)命令を利用します。all
スカラー値とデータ並列性
周辺コード内のスカラ値(ループカウンターや定数など)は各チェインによって同一に計算されるため、通常の CUDA と同様、ワープロム全体へ複製されます。
- ユニフォーム: 単なる
はユニフォームです。f32 - バリエーブル:
はバリエーブルです。Simd<f32, 32>
中間表現(IR)と安全性
VectorWare では IR を Rust の型システム内へ符号化しています。
- 型付けされた演算: ボールト、シャッフル、合計、スキャン、集約、アトミック操作などが型付きで定義されます。
- エラー防止: オペランドや実行形状も型付けされるため、無効なプログラムはコンパイル段階で阻止されます。
- コストゼロの降下: 手書きの PTX を参照する必要なく、IR が直接対応する命令へと降下します。
5. メリットとデメリット
✅ メリット
- ソースコードの共通化: 同じソースコードが CPU および GPU で動作します。移植可能 SIMD を利用している既存のコードも GPU 実行候補となります。
- 抽象化のコストなし:
は普通のリスト所有値です。Borrow Checker やライフタイムなど、Rust の型システムが CPU と同様に適用されます。GPU 固有のベクトルタイプを追加する必要はありません。Simd<T, N> - 既存コードの活用: 未変更の CPU コードでも GPU のチェインレベル並列性を活用可能です。
⚠️ デメリットと注意点
- 安定性の欠如:
はまだ Rust 内で不安定な機能です。ナイトリービルドでcore::simd
が必須であり、インターフェースに変更が生じる可能性があります。#![feature(portable_simd)] - ベクトル幅の一致: 抽象化のコストゼロ性は、ベクトル幅(N)がワープロムのチェイン数(32 または 64)と一致する場合のみ保証されます。
- N が小さい場合:一部のチェインがアイドル状態になります。
- N が大きい場合:一部または全てのチェインが複数の要素を処理しなければなりません。
- シャッフルの制約: ハードウェアがサポートする特定の置換パターンのみが安価です。任意の置換は複数命令や共有メモリを必要とします。また、横断演算はスケジューラによるタスクの重なり合いに制限を受けます。
- コンパイラの未踏領域: この抽象化の一貫性を確保するためにコンパイラの変更が必要で、全てのケースをカバーしたか確信を持っていません。
6. 今後の展望と戦略
次のステップ:統合
SIMD、スレッド、非同期処理がすべて GPU にマッピングされた後の自然なステップは、それらを統合することです。
- スレッドがタスクをワープロム間で分散させる。
が各ワープロム内のチェイン間でデータを分散させる。core::simd- 非同期処理がこれらの間における並列性を構造づける。
マトリックスとベクトライゼーション
- マトリックス形状の SIMD を GPU のテンソルコアへと降下させることを検討中です。
- スカラ Rust ループを自動的に Simd 操作へベクトライゼーションし、
に依存せずともワープロムレベルの並列性を導入する手法も探求しています。core::simd
ベクトル表現の再考
CPU と GPU で共有されるベクトル表現は価値がありますが、現在の
core::simd タイプがその基礎に適しているかは未だ不確かです。さらなる探求が必要となります。
VectorWare のスタンス
- Rust への注力: GPU における進歩のスピードは Rust の抽象化とエコシステムの力量を示しています。VectorWare は高性能かつ信頼性の高い GPU ネイティブアプリケーション開発において、Rust が最も適していると信じています。
- 多言語対応も視野に: 現時点では Rust に注力していますが、今後の製品では複数のプログラミング言語およびランタイムをサポートする予定です。
7. 追跡情報
最新の情報は以下のチャネルで共有されます。
- SNS: X(旧 Twitter)、Bluesky、LinkedIn
- ブログ: VectorWare の公式ブログ
- お問い合わせ:
hello@vectorware.com
今後数ヶ月間で、作業の詳細についてさらに詳しく共有してまいります。