WebGPU vs WASM | C++ vs Rust | Web時代のアーキテクチャ

Webで重い処理をやろうとすると、「結局サーバーで計算するか」「C++を書いてWASMにするしかない」という話になりがちでした。
この前提は長い間正しかったのですが、ここ数年で静かに、しかし決定的に変わりつつあります。
その変化の中心にあるのが WebGPU です。
本記事では、WebGPUの登場によって何が変わったのか、WASMはなぜまだ重要なのか、そして「C++以外の選択肢」をどう考えるべきかを整理します。
WebGPUは「WebGLの後継」以上の存在
WebGPUは、ブラウザからGPUを直接扱うための新しい標準APIです。
名前だけ見ると「WebGLの置き換え」に見えますが、実態はもう少し踏み込んだ存在です。
これまでのWebGLは、あくまで「描画のためのAPI」でした。一方WebGPUは、描画と計算をはっきり分けています。
描画はRender Pipeline、計算はCompute Pipeline。このCompute Pipelineによって、ブラウザ上でも本格的なGPU並列計算が可能になりました。
ここで重要なのは、「JSが速くなった」のではない、という点です。
JSはほとんど計算していません。
JSはGPUに渡す命令を組み立て、実行を指示しているだけです。実際の計算は、GPUが非同期に処理します。
つまり、WebGPUは「JSが遅い問題」を、JSに計算をさせないことで解決しています。
非同期実行モデルが前提になっている
WebGPUは最初から「待たない設計」です。
JSやWeb WorkerでGPU用のコマンドを記録し、それをGPUキューに投げると、その瞬間にJS側の処理は返ってきます。
GPUは裏で計算を続け、結果が必要になったタイミングでだけ Promise を通じて受け取ります。
この間、UIスレッドは止まりません。入力も描画も普通に動き続けます。
そのため「JSはシングルスレッドだから重い計算ができない」という制約は、WebGPUの世界では本質的な問題ではなくなりました。
それでもWASMが必要な理由
では、すべてGPUに投げてしまえばよいのでしょうか。
答えは「No」です。
GPUが得意なのは、大量の同じ処理を一気に並列実行することです。行列演算、画像処理、粒子計算などは非常に速くなります。
一方で、分岐が多く、状態を持ち、処理の流れが複雑なロジックはGPUに向きません。
こうした処理は、今でもCPUの方がはるかに扱いやすく、速く実装できます。
この「GPUに向かないが、JSで書くには重い」領域を担うのがWASMです。
「JSが遅いからWASM」は少し違う
よくある説明として「JSは遅いからWASMを使う」という言い方がありますが、これは少し雑です。
JSは、UIやイベント処理、非同期制御といった用途では非常に優秀です。
問題になるのは、数値演算が多いループや、メモリ局所性が重要な処理です。
JSは動的型で、数値も基本的に double です。メモリ配置を厳密に制御することもできません。
そのため、CPUを「CPUらしく」使う処理には向かないだけです。
WASMが速い理由は、マルチスレッドだからでも、魔法がかかっているからでもありません。
静的型で、明確なメモリレイアウトを持ち、コンパイラ最適化やSIMDを活かせる、ただそれだけです。
GPUとWASMの役割分担が前提になる
ここまで整理すると、自然に役割分担が見えてきます。
大量の同型計算や行列・画像処理はGPUへ。
複雑な分岐や状態管理が必要な処理はWASMへ。
JSは全体の制御とUIに集中する。
この前提に立つと、「CPU側の処理は極限まで速くある必要はない」という見方もできます。
本当に重い計算はGPUに逃がせるからです。
WASM=C++という思い込みについて
ここで必ず出てくるのが、「GCなしで完全にメモリを管理するなら、結局C++では?」という疑問です。
確かに歴史的にはその通りでした。
C++は、GCなしで最高性能を出せる言語です。
ただし、WASMという実行環境を前提にすると、話は少し変わります。
WASMはもともとGC前提ではなく、線形メモリを自分で管理するモデルです。最終的に生成されるコードは、どの言語で書いても同じ土俵に落ちます。
つまりWASM=C++必須ではありません。
Rustが現実的な選択肢として浮上している理由
C++がWASMを開発する上での唯一の選択肢ではない最大の理由、それはRustの存在です。
RustはGCを持たず、所有権モデルによってメモリ安全性を担保します。
性能はC++に近く、WASMとの相性も非常に良い。JSとの連携事例も多く、ツールチェーンも成熟しています。
何より、「生理的にC++が無理」という感覚を回避できます。
長期運用を考えると、これは無視できないポイントです。
JS + Rust + WebGPU という構成は、性能・安全性・採用のバランスが非常に良い組み合わせです。
人材・採用という現実的な視点
技術選定は、純粋な性能比較で決められるものではありません。
C++人材はどうしても組み込み寄りになりがちで、Webの文化や非同期モデルに馴染まないケースもあります。
一方、RustやC#、Web系の人材は、非同期処理やサービス開発に慣れており、フロントエンドとの連携もスムーズです。
技術は「書けるか」よりも「継続して運用できるか」の方が重要です。
現時点での現実的な構成
最終的に見えてくる構成は、かなりシンプルです。
メインスレッドではUIと状態管理を行い、Web WorkerでRust/WASMによるCPU向け処理とWebGPUの制御を行う。
GPUはCompute Shaderで並列計算を担当する。
JSは司令塔、Rustは思考役、GPUは実働部隊。
この分業が、これからのWeb計算の基本形になっていきます。
まとめ
WebGPUによって、「Webは遅い」という前提は崩れました。
WASMは、GPUでは扱いにくい複雑ロジックの受け皿として今後も重要です。
C++は依然として最強ですが、必須ではありません。
これからの選択肢は一つではありません。
JSで制御し、Rustで考え、GPUで走る。
そのくらいの距離感が、今のWebにはちょうどいいように思います。