01独立並列から行列演算へ
前回の記事(WebGPU は本当に最速か — モンテカルロ資産シミュレーションで実測比較)では、各試行が完全に独立した並列計算を扱った。1万通りの資産推移を同時にシミュレートするような計算で、そこでの結論は「WebGPUが常に最速とは限らない」——小規模ではGPUの起動コストがCPUを上回る、というものだった。
今回は計算の質を変える。行列演算(線形代数)だ。行列積は各出力要素が他の多くの要素に依存し、メモリアクセスのパターンが性能を大きく左右する。GPUベンチマークの定番であると同時に、ポートフォリオ最適化(マルコウィッツの平均分散最適化)の中核でもある。最適化は突き詰めると、共分散行列の計算(行列積)とリスク評価(行列・ベクトル積)に分解できるからだ。
そこで本記事では、まず行列積をWebGPUで実装してベンチマークし、その基盤の上に共分散行列・ポートフォリオ評価を載せ、最終的に効率的フロンティアを描くところまでを追う。すべて単一のWGSLエンジンで実装し、CPUと結果が一致することを確認しながら進めた。
・Google Pixel 10 Pro(Android, WebGPU)
・iPad mini A17 Pro(iPadOS, WebGPU)
・比較対象:純粋なJavaScript(CPU・単一スレッド)
・単位:ミリ秒、小さいほど速い。計測値は参考値で環境により変動します。
02行列積 — naive と tiled の実装
行列積 C = A × B は、出力 C[i][j] が「Aのi行とBのj列の内積」で決まる。各出力要素は独立に計算できるので、GPUでは「1スレッド=1出力要素」で並列化できる。実装は2種類用意した。
タイル化は、行列をタイル(小ブロック)に分け、ワークグループの共有メモリに載せてから計算する手法だ。グローバルメモリより高速な共有メモリで値を再利用することで、メモリ帯域のボトルネックを緩和する——というのが理屈である。本当にそうなるか、正方行列のサイズを64〜1024まで変えて計測した。
03タイル化の深掘り — 最適サイズは32だった
当初、タイルサイズを16×16で実装したところ、奇妙な結果になった。tiled が naive に負ける場面があったのだ。「タイル化は効かないのか?」と疑ったが、タイルサイズを8・16・32と変えて比較すると、原因は明白だった。
workgroupBarrier)のコストだけがかかる。32×32(1024スレッド/ワークグループ)でようやく、共有メモリに載せた値の再利用が十分に効き、グローバルメモリアクセスが激減する。最適タイルサイズはGPUに依存し、実測でしか分からない——が、今回試した2機種はともに32が最適だった。
この発見を受けて、エンジンのデフォルトタイルサイズを32に変更した。その効果は劇的で、Pixel 10 Pro の 1024×1024 では 修正前 191ms → 修正後 45ms(約4倍)、512×512 では 29ms → 5ms(約6倍)まで改善した。同じタイル化でも、サイズ一つで性能が一変する。
04金融への応用 — 共分散行列
ここからが本題だ。最速の行列積が手に入ったので、これを金融計算に応用する。最初の応用が共分散行列である。資産のリターン時系列から、資産同士がどう連動するかを表す行列を作る。
Xは「n期間 × m資産」のリターン行列。XᵀX は転置を含む積だが、これは「Xの列iと列jの内積」なので、Xを明示的に転置せず専用シェーダーで直接計算した。各スレッドが共分散行列の1要素(i,j)を担当し、期間方向に走査して内積を取る。
共分散行列のサイズは資産数mで決まる(m×m)。CPUとWebGPUで計算し、誤差は1e-3〜1e-4(f32の丸め誤差レベル、中心化を含むため行列積よりやや大きい)で一致した。資産数を変えた計測結果が次だ。
05ポートフォリオ最適化 — 効率的フロンティアを並列評価で描く
共分散行列Σと期待リターンμが揃えば、ポートフォリオのリスクとリターンを評価できる。配分ベクトルw(各資産の比率、合計1)に対し、
マルコウィッツ理論の効率的フロンティア(同じリスクで最大リターンとなる配分の境界)は、解析的には共分散行列の逆行列で求まる。だが逆行列はGPUの並列化に向かない(逐次性が強い)。そこで本記事では別の道を採った——数万通りの配分をランダムに生成し、すべてGPUで並列評価して、散布図の外縁としてフロンティアを浮かび上がらせる方法だ。各GPUスレッドが1つの配分を担当する、独立並列(#1)の構造がここで再び活きる。
4資産(国内債券・国内株式・先進国株式・新興国株式)のサンプル市場で、5万通りの配分を評価した結果が次の散布図だ。
5万通りの配分を WebGPU で評価(実機では約1ms)。左に凸の「弾丸型」がリスク・リターンの実現可能領域。上側の外縁が効率的フロンティア。★が最大シャープ配分、◆が最小分散配分。
06資産数スケーリング — いつGPUが効くか
ところが、4資産でのポートフォリオ評価のベンチマークでは、意外にもGPUの優位は小さかった(CPUと同程度〜2.5倍)。1配分あたりの計算 wᵀΣw が、4資産では16回の積和と軽すぎるためだ。では資産数を増やすとどうなるか。計算量はO(m²)で増える。
07結論 — GPU優位を決めるもの
3種類の線形代数をWebGPUで実装し、2機種で計測して見えたのは、一貫した構造だった。
| ワークロード | GPU優位のピーク | クロスオーバー |
|---|---|---|
| 行列積(共有メモリ集約) | 88〜115倍 | ~256 |
| 共分散行列(中規模) | 7倍〜 | ~64資産 |
| ポートフォリオ評価(軽量並列) | 9.9倍 | ~16資産 |
どのワークロードにも「ある規模を超えるとGPUが優位になる」というクロスオーバーが存在した。逆に言えば、規模が小さいうちはCPUで十分であり、GPUの起動・転送コストがかえって足を引っ張る。これは#1のモンテカルロ(独立並列)から一貫する主題だ。
さらに今回は、同じアルゴリズムでも実装パラメータ一つ(タイルサイズ)で性能が一変することも分かった。tiled-16 では naive に負け、tiled-32 で10倍速くなる。GPUプログラミングでは「並列化すれば速い」という素朴な期待は通用せず、メモリ階層を意識した実装と、実測による検証が欠かせない。
実務的な指針はこうまとめられる。数資産の単純な計算ならCPUで十分。数十〜100超の銘柄を扱う本格的な分散投資、あるいは大きな行列を伴う計算では、WebGPUが10倍級の高速化をもたらす。ブラウザだけで、サーバーもインストールも不要で、この計算力が手に入る——それがWebGPUの面白さだと思う。