# NPY ファイルからの行列積の速度比較
同じ NPY ファイルを CPU と GPU で読み込み、行列積の完了までと、全結果の取り出しまでを比較します。
README には256×256・512×512・1024×1024の結果を掲載しています。
演算を含まない読み書きの比較は[NPY 入出力の速度比較](file-io-benchmarks.md)にあります。
本体 0.10.0 の変更前後の計測は[専用バックエンドへの移行確認](backend-validation.md)にあります。
## 測定範囲
CPU は Rust の `npy-codec` で NPY を MessagePack に復号し、Nu の `from msgpack | into matrix` で行列に変換してから `matrix multiply` を実行します。
ファイル読込、codec の外部プロセス起動、MessagePack 出力と Nu での復号、行列への変換を含みます。
Rust から NPY を直接 CPU 行列へ読み込む最短経路の性能ではありません。
GPU は `vulkan matrix from-npy` で2つのファイルを読み、`vulkan matrix multiply` を実行します。
通常入力は GPU へコピーし、共有入力は `--shared` でファイルマッピングを保持します。
どちらも演算完了を待ちます。コマンドを GPU に投入するだけの時間ではありません。
- 行列として保持:入力読込から演算完了まで。結果値の破棄も計時に含みます。
- Nu 取出込:上記に加え、CPU/GPU の全結果を `into-nu` で Nu のリストへ変換します。
## 結果
f64、10回平均。単位は ms です。
以下の PHOENIX は AMD Radeon 780M(Ryzen 9 8945HS 内蔵)のドライバー上の表示名です。生データとの対応のため、この文書では PHOENIX と表記します。
### 256×256
| CPU native matrix | 18.101 | 20.355 |
| RX 7800 XT 通常入力 | 39.828 | 60.780 |
| RX 7800 XT 共有入力 | 11.515 | 42.653 |
| RX 7600 通常入力 | 6.397 | 25.316 |
| RX 7600 共有入力 | 4.831 | 25.326 |
| PHOENIX 通常入力 | 8.676 | 27.277 |
| PHOENIX 共有入力 | 5.298 | 23.703 |
### 512×512
| CPU native matrix | 66.691 | 76.752 |
| RX 7800 XT 通常入力 | 40.574 | 102.449 |
| RX 7800 XT 共有入力 | 15.011 | 100.750 |
| RX 7600 通常入力 | 12.008 | 84.707 |
| RX 7600 共有入力 | 9.431 | 83.115 |
| PHOENIX 通常入力 | 17.590 | 90.586 |
| PHOENIX 共有入力 | 14.056 | 89.186 |
### 1024×1024
| CPU native matrix | 255.713 | 301.542 |
| RX 7800 XT 通常入力 | 53.014 | 348.453 |
| RX 7800 XT 共有入力 | 28.432 | 324.072 |
| RX 7600 通常入力 | 42.537 | 331.522 |
| RX 7600 共有入力 | 27.669 | 318.605 |
| PHOENIX 通常入力 | 72.145 | 363.253 |
| PHOENIX 共有入力 | 43.970 | 352.458 |
RX 7800 XT の通常入力は CPU の約4.8倍の速度でしたが、全結果を Nu に取り出すと CPU の方が速くなりました。
後者には GPU からの転送だけでなく Nu のリストへの変換も含まれるため、差をメモリ転送だけの時間とは解釈できません。
内蔵 GPU の PHOENIX では、共有入力により72.145 msから43.970 msへ短縮しました。
これはファイル読込と行列積を合わせた比較です。共有入力は GPU コピーを省きますが、マッピングと import、演算のコストは残ります。
同一物理ページの利用やページテーブルの張り替えだけで処理されることを測定・保証した結果ではありません。
共有入力は必要な条件を満たす離散 GPU でも利用できます。[対応形式と利用条件](file-io.md)を参照してください。
## 条件
- 測定日:2026-10-17。測定対象は commit `4d71e33e60769892aaeb81ff43d4f493ad7d62e9`、plugin/validation ともに0.9.0。
- 同じ C順序・little-endian f64 の NPY ファイルを両経路で使用。データ開始位置は4096 bytes。
- warm page cache、warmup 2回、測定10回。ディスクの cold read 性能は測定していません。
- `RAYON_NUM_THREADS=1`、`MATMUL_NUM_THREADS=1`。各 round で経路の実行順を回転。
- 密行列の入力は `A[i,j]=((3i+j) mod 7)-3`、`B[i,j]=((5i+j) mod 7)-3`。
- 元の測定は64/256/1024角、scale/行列積、2つの計測範囲、CPUと3 GPUの通常/共有入力で全84条件・840測定。
- 512角は2026-10-17に同じスクリプト・バイナリ・warmup・回数・スレッド設定で追加測定。scale/行列積、2つの計測範囲、7経路で全28条件・280測定。サイズ間は同時測定ではありません。
- 入力を codec で読み戻し、全条件の出力を CPU と計時外で照合。測定中に本作業のビルドや別ベンチは実行していません。
この表はファイル読込からの比較です。入力を準備済みの計算だけの比較や、Nu のリストから入力する比較とは区別してください。
再実行には `validation/benches/file-compute.nu` を使います。ビルドと実行手順は[開発と検証](development.md)にあります。
元の測定の[生データ](bench/file-compute-original.csv)と[集計](bench/file-compute-original.nuon)、512角の[生データ](bench/file-compute-512.csv)と[集計](bench/file-compute-512.nuon)を収録しています。
512角の追加測定は同スクリプトの `--sizes 512` を指定し、他の条件は変更していません。