モバイル&ワイヤレスブロードバンドでインターネットへ

gwaw.jp
 
GPU COMPUTE BENCHMARK #2

WebGPUで線形代数は速くなるか
— 行列積からポートフォリオ最適化まで

行列積・共分散行列・ポートフォリオ評価。3種類の線形代数をWebGPU(WGSL)で実装し、Pixel 10 Pro と iPad mini (A17 Pro) で実測した。見えてきたのは「GPUは万能ではなく、計算の規模と質で優位が決まる」という一貫した構造だった。

WebGPUWGSLmatmul 共分散行列ポートフォリオ最適化タイル化

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種類用意した。

naive : 各スレッドがグローバルメモリを直接読んで内積 tiled : タイルを共有メモリ(var<workgroup>)に載せ、 メモリアクセスを削減してから計算

タイル化は、行列をタイル(小ブロック)に分け、ワークグループの共有メモリに載せてから計算する手法だ。グローバルメモリより高速な共有メモリで値を再利用することで、メモリ帯域のボトルネックを緩和する——というのが理屈である。本当にそうなるか、正方行列のサイズを64〜1024まで変えて計測した。

▍ Google Pixel 10 Pro
▍ iPad mini (A17 Pro)
KEY FINDING 01 クロスオーバーは256前後。小さな行列ではCPUが速いことすらある。 64×64ではGPUの起動コストが目立ち、CPUと拮抗する。256×256を超えるとGPUが逆転し、512×512では tiled が CPU比で Pixel 88倍/iPad 115倍。行列積の計算量はO(n³)で増えるため、行列が大きいほど並列化の価値が跳ね上がる。#1の独立並列と同じ「小規模ではGPUが最速とは限らない」構造が、行列積でも現れた。

03タイル化の深掘り — 最適サイズは32だった

当初、タイルサイズを16×16で実装したところ、奇妙な結果になった。tiled が naive に負ける場面があったのだ。「タイル化は効かないのか?」と疑ったが、タイルサイズを8・16・32と変えて比較すると、原因は明白だった。

▍ タイル構成比較(1024×1024、最速を緑で表示)
KEY FINDING 02 「タイル化すれば速い」は不正確。タイルサイズが成否を分ける。 両機種とも、全サイズで tiled-32 が最速だった。一方 tiled-8 は naive より遅いことすらある。タイルが小さいと、共有メモリの恩恵が乏しいのに、ロードと同期(workgroupBarrier)のコストだけがかかる。32×32(1024スレッド/ワークグループ)でようやく、共有メモリに載せた値の再利用が十分に効き、グローバルメモリアクセスが激減する。最適タイルサイズはGPUに依存し、実測でしか分からない——が、今回試した2機種はともに32が最適だった。

この発見を受けて、エンジンのデフォルトタイルサイズを32に変更した。その効果は劇的で、Pixel 10 Pro の 1024×1024 では 修正前 191ms → 修正後 45ms(約4倍)、512×512 では 29ms → 5ms(約6倍)まで改善した。同じタイル化でも、サイズ一つで性能が一変する。

04金融への応用 — 共分散行列

ここからが本題だ。最速の行列積が手に入ったので、これを金融計算に応用する。最初の応用が共分散行列である。資産のリターン時系列から、資産同士がどう連動するかを表す行列を作る。

Σ = (1/(n-1)) X'ᵀ X' (X' は列ごと中心化)

Xは「n期間 × m資産」のリターン行列。XᵀX は転置を含む積だが、これは「Xの列iと列jの内積」なので、Xを明示的に転置せず専用シェーダーで直接計算した。各スレッドが共分散行列の1要素(i,j)を担当し、期間方向に走査して内積を取る。

共分散行列のサイズは資産数mで決まる(m×m)。CPUとWebGPUで計算し、誤差は1e-3〜1e-4(f32の丸め誤差レベル、中心化を含むため行列積よりやや大きい)で一致した。資産数を変えた計測結果が次だ。

▍ 共分散行列の計算時間(iPad mini A17 Pro)
KEY FINDING 03 共分散行列は、資産64以上でGPUが優位に。 16〜32資産まではCPUと拮抗するが、64資産で約7倍、1000期間×128資産ではCPU 28msに対しGPUはほぼ瞬時。現実の金融では、日本株の主要銘柄(数十〜100超)×数年の日次データ(年252日×数年)という規模がふつうにあり、そこではGPUが明確に効く。

05ポートフォリオ最適化 — 効率的フロンティアを並列評価で描く

共分散行列Σと期待リターンμが揃えば、ポートフォリオのリスクとリターンを評価できる。配分ベクトルw(各資産の比率、合計1)に対し、

リスク σ = √(wᵀΣw) 期待リターン μp = wᵀμ

マルコウィッツ理論の効率的フロンティア(同じリスクで最大リターンとなる配分の境界)は、解析的には共分散行列の逆行列で求まる。だが逆行列はGPUの並列化に向かない(逐次性が強い)。そこで本記事では別の道を採った——数万通りの配分をランダムに生成し、すべてGPUで並列評価して、散布図の外縁としてフロンティアを浮かび上がらせる方法だ。各GPUスレッドが1つの配分を担当する、独立並列(#1)の構造がここで再び活きる。

4資産(国内債券・国内株式・先進国株式・新興国株式)のサンプル市場で、5万通りの配分を評価した結果が次の散布図だ。

5万通りの配分を WebGPU で評価(実機では約1ms)。左に凸の「弾丸型」がリスク・リターンの実現可能領域。上側の外縁が効率的フロンティア。★が最大シャープ配分、◆が最小分散配分。

KEY FINDING 04 逆行列を使わずに、効率的フロンティアが描けた。 5万通りの並列評価だけで、教科書通りの弾丸型が現れる。GPUなら一瞬で、リスク・リターン平面の全体像と最適配分(シャープレシオ最大の接点ポートフォリオ)が見える。解析解に頼らない、力任せだが直感的な最適化のアプローチだ。

06資産数スケーリング — いつGPUが効くか

ところが、4資産でのポートフォリオ評価のベンチマークでは、意外にもGPUの優位は小さかった(CPUと同程度〜2.5倍)。1配分あたりの計算 wᵀΣw が、4資産では16回の積和と軽すぎるためだ。では資産数を増やすとどうなるか。計算量はO(m²)で増える。

▍ 資産数スケーリング(5万配分固定、iPad mini A17 Pro)
KEY FINDING 05 クロスオーバーは16資産付近。それを超えるとGPU優位が拡大。 4資産ではCPUが勝つ(GPU 0.6×)が、16資産で逆転し、128資産では CPU 594ms vs GPU 60ms(9.9倍)。CPUは資産数の二乗で重くなるのに対し、GPUは並列化でその増加を吸収する。「ポートフォリオ評価はGPU優位が出にくい」という当初の印象は、資産が少ないとき限定だった。多数の銘柄を扱う本格的な分散投資では、GPUが確実に効く。

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の面白さだと思う。

『WebGPUで線形代数は速くなるか — 行列積からポートフォリオ最適化まで』を公開しました。