JavaScriptはどれくらい速いのか? 2,000万個の粒子シミュレーション
課題
- スマートフォンでCPUのみを使い、60fpsで1,000,000個の粒子をシミュレートすること
最初の試み
- GPUを使わず、CPUのみを使ってJavaScriptで粒子をシミュレート
- JavaScriptの配列は常に連続したデータ配列ではない
- TypedArrayを使ってメモリを連続した状態に維持
最初の実装
- Web Workersを使ってマルチスレッド化を実装
- SharedArrayBufferを使ってメモリを共有
- 粒子データを32ビット浮動小数点数として保存
- ImageDataオブジェクトを使って各粒子を画面上のピクセルとしてレンダリング
2回目の試み
- 入力データをワーカーに渡してインタラクションを追加
- 画面のタッチポイントに粒子が引き寄せられるよう、重力の近似を使用
3回目の試み
- ワーカーがピクセルを描画するようにして、すべてのCPUコアをより活用
- メモリ使用量の増加を受け入れつつ、さらなる高速化を期待
4回目の試み
- レンダリング完了までスレッド間の同期のためにメッセージングを使用
- flickeringの問題を解決
5回目の試み
- ダブルバッファリングを使い、レンダリング中にワーカーが次のフレームを準備できるようにする
- メモリ使用量が増加
6回目の試み
- 粒子が開始位置に戻るようにする新しいインタラクションのアイデアを追加
- 粒子の開始位置を保存するために2つの数値を追加
GN⁺の要約
- この記事は、JavaScriptで大規模な粒子シミュレーションを実装する方法を説明している
- TypedArrayとWeb Workersを使ってCPU性能を最大限に活用する方法を扱っている
- マルチスレッド化とメモリ管理の重要性を強調している
- 粒子シミュレーションのインタラクティブ性を高めるためのさまざまな試みを示している
- 類似機能を持つプロジェクトとしてThree.jsとBabylon.jsがある
1件のコメント
Hacker Newsの意見
ブログにシミュレーションを直接埋め込むことを提案
ciechanow.skiサイトを例として提示WebGPUがなくてもGPU上でパーティクルシミュレーションを実行できると言及
モバイルでのデモが非常に印象的だと言及
パーティクルデータを単一のJS数値にエンコードできるか質問
MAX_SAFE_INTEGER範囲内でデータを表現できる可能性を探るAtomics APIについて質問を提起
waitAsyncを除いてはPromiseを使わないと説明ほぼ2,000万個のパーティクルを扱うシミュレーションに言及
動画は素晴らしいが、MacOS ChromeデスクトップではCodeSandboxのリンクが動作しないと言及
SharedArrayBufferが未定義というエラーとCORSエラーが発生UIチームにJSの高速な性能を見せたいと言及
著者の優れたエンジニアリングと素晴らしい文章に感謝
類似の実験を通じて、多数のパーティクルを基本的な物理シミュレーションで処理した経験を共有
chrome://tracingがより多くのインサイトを提供できると言及