
2026/07/17 23:24
85.3 GFlops:単一のAMD Zen 3 コアにおけるFP32行列乗算の最適化
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
まとめ:
本研究では、AMD Zen 3 CPU 上で OpenBLAS のような主要ライブラリと同等のパフォーマンスを実現する、AVX2/FMA インプリシティブ(インtrinsic)を用いた C++ 実装による行列乗算(GEMM)を提示する。この実装は最高で 85.30 GFLOPS の性能を発揮し、理論上のピーク性能(134.4 GFLOPS)の 63.5% に達した。キャッシュおよびレジスタブロッキング戦略を組み合わせた 28 つの構成を検証した結果、K および B に対してブロックサイズを 256 とする最適なモデルが得られ、この設定により L2 キャッシュ内でのデータ再利用を最大化しつつ、L3 ポリューションや TLB ミスを招く完全な転置手法と比較して回避できる。主要な最適化には、命令のレイテンシを効果的に隠すために FMA チェインリング(chain4)を用いること、適切な 32 バイトのメモリアラインメントによる約 5% のパフォーマンス向上、および壊的な非時間的ストア(destructive non-temporal stores)を避けることで、劇的な性能低下を防ぐことが含まれる。一方、積極的なソフトウェアによるプリフェッチは、効率的なネイティブハードウェアプリフェッチにより約 8% パフォーマンスが阻害されるため行われない。Ryzen 5 5500 で 2048×2048 の行列を用いてテストされ、この最適化されたコードは、GCC 12.2 以降および特定のフラグを必要とし、MIT ライセンスによる軽量な代替手段を提供し、参照実装とビット単位で同一の結果を得る。UFRN に所属する Lucas Lima Freitag によって 2025 年に発表されたこの研究は、最新の AMD プロセッサにおいてピーク効率を達成するには、ターゲット指向の低レベル調整が不可欠であることを示している。
本文
AMD Zen 3 アーキテクチャ向けの GEMM 最適化:理論ピークの 63.5% を達成
📖 概要
本リポジトリは、AMD Ryzen 5 5500(Zen 3 アーキテクチャ)における単一コア・単精度浮動小数点演算(FP32)の行列乗算(GEMM)最適化に関する体系的な調査成果です。キャッシュブロッキング、レジスタブロッキング、FMA 連結などの**28 の異なる設定(モデル MX01 〜 MX28)**が評価されました。
- 主要な最適化技術
- Cache blocking (tiling): L1/L2/L3 キャッシュの範囲内にブロックを収めるための BI, BJ, BK 調整
- Register blocking: YMM レジスタ(最大 16 つ)に C の蓄積子を保持(2〜8 ラインの実験)
- FMA chaining: chain1 から chain6 までの命令連結
- Packing strategies: パッキングなし、転置(Transpose)、B-pak on-the-fly など
- Memory alignment: 32 バイトアラインメント
- Software prefetching:
を使用した手法_mm_prefetch - Non-temporal stores: Stream store の採用
最高のモデルである MX24 は 85.30 GFLOPS という性能を発揮し、単純な実装より 56.5 倍も高速化されました。AMD AOCL や OpenBLAS などの最適化ライブラリと同等の結果を達成しています。
🏆 主要な結果
| モデル | 構成要素 | GFLOPS | ピーク理論値 (%) |
|---|---|---|---|
| MX24 | 4 ライン + chain4 + B-pack (BK=256) | 85.30 | 63.5% |
| MX22 | 4 ライン + chain4 + B-pack (BK=128) | 84.10 | 62.6% |
| MX23 | 4 ライン + chain4 + B-pack (BK=64) | 82.93 | 61.7% |
| MX16 | 4 ライン + chain4 + アラインメント(パッキングなし) | 72.58 | 54.0% |
| MX20 | 4 ライン + chain4 + Bᵀ(転置) | 79.21 | 58.9% |
| MX18 | 4 ライン + chain4 + プリフェッチ | 79.75 | 59.3% |
💡 ピーク理論値の計算式
$$ \text{ピーク性能} = \text{FMA コア} \times 2 \times \text{float 数} \times 8 \times \text{演算回数} \times 2 \times \text{周波数} $$
- 計算結果:$134.4 \text{ GFLOPS}$(AMD Ryzen 5 5500 の定格動作時)
🔬 研究方法論と技術詳細
評価された最適化技術の詳細
- Cache Blocking (Tiling)
- BI, BJ, BK を調整し、ブロックを L1(32 KB)、L2(512 KB)、L3(16 MB)キャッシュ内に維持します。
- 最適な結果:
で達成され、L2 キャッシュを超えずにリユースを最大化しました。BK=256
- Register Blocking
- C の蓄積子を YMM レジスタ(最大 16 つ使用可能)に保持します。
- 最適な結果:
が最良のバランスを示し、追加のスパイル(spill)が発生しますが、A の再利用率のコストを上回る性能をもたらしました。4 ライン
- FMA Chaining
- Zen 3 における FMA 命令のラテンシーは 4 サイクルです。
(4 つの独立した蓄積子)がこのラテンシーを隠蔽し、2 つの FMA コアを最大限活用します。chain4
- Packing (パッキング)
- 「on-the-fly B-pack」: B のブロック(BK×BJ)を連続バッファにコピーし、不連続アクセスを順次アクセスに変換します。
- 完全な転置(L3 キャッシュ汚染)や直接アクセス(TLB ミスの影響受けやすさ)よりも優れています。
- Alignment (アラインメント)
でアラインメントされたメモリを使用し、_mm_malloc(..., 32)
指令を適用することで約 5% の性能向上が見られました。vmovaps
- Prefetching (プリフェッチ)
- Zen 3 はストリーミングパターンに対してハードウェアプリフェッチが効率的であるため、ソフトウェアによる
を使用するとパフォーマンスが約 8% 低下しました。_mm_prefetch
- Zen 3 はストリーミングパターンに対してハードウェアプリフェッチが効率的であるため、ソフトウェアによる
- Non-temporal Stores (非時限ストア)
を採用した場合の結果は壊滅的(1.24 GFLOPS)でした。_mm256_stream_ps- 原因: C が「読み込み・修正・書き込み」されるため、各書き込みでキャッシュラインが無効化され、DRAM の再ロードが頻発するためです。
📂 リポジトリの構成
zen3-gemm/ ├── README.md ├── src/ │ └── mx85.c # 28 モデルを含む完全なソースコードとベンチマーク ├── docs/ │ ├── artigo_en.tex # 学術論文(LaTeX 形式) │ └── resultados/ # ベンチマーク出力ログ │ ├── mx85_benchmark.txt │ └── mx85_output8.txt └── build/ └── Makefile # コンパイルオプション(任意)
⚙️ コンパイルと実行方法
前提条件
- プロセッサ: AVX2 と FMA をサポートする CPU(AMD Zen、Intel Haswell 以降など)
- OS: Windows (10/11) または Linux
- コンパイラ: GCC 12.2+(Windows では MinGW-w64 推奨)または対応コンパイラ
- メモリ: 行列サイズ 2048×2048 の演算に必要な約 48 MB(3 つの行列分)
コンパイルコマンド (GCC)
src/ ディレクトリに移動し、以下のコマンドを実行してください。
gcc -O3 -mavx2 -mfma -march=native -funroll-loops -frename-registers -o mx85.exe mx85.c
重要なフラグ解説:
: SIMD 指令を有効にし、現在の CPU に最適化します。-mavx2 -mfma -march=native
: 内部ループの展開を行います(パフォーマンス向上)。-funroll-loops
: レジスタ割り当てを改善し、スパイル(spill)の削減に寄与します。-frename-registers
実行と出力
プログラムは以下の動作を行います:
- Windows においてはスレッドアフィニティをコア 0 に適用し、優先度を高設定にします。
- 各モデルについてウォームアップ 3 回、測定 15 回の合計で計測を実行します。
- 以下のファイルを生成します:
: 完全なランキングと検証データmx85_benchmark.txt
: 参照実装との最大誤差mx85_validate.txt
カスタマイズ方法:
- 特定のモデルのみテスト:
関数を修正して、対象となる関数(例:main()
)を直接呼び出します。mx24(A, B, C, N) - 行列サイズ変更: 行数に関する定数
(ソースコード約 230 行目)を変更してください。N
📊 完全結果表(全体ランキング)
以下に評価されたすべての 28 モデルの測定 GFLOPS と理論ピーク値に対する百分比を示します。
| 順位 | モデル | 構成要素 | GFLOPS | ピーク理論値 (%) |
|---|---|---|---|---|
| 1 | MX24 | 4 ライン + chain4 + B-pack BK=256 | 85.30 | 63.5% |
| 2 | MX22 | 4 ライン + chain4 + B-pack BK=128 | 84.10 | 62.6% |
| 3 | MX23 | 4 ライン + chain4 + B-pack BK=64 | 82.93 | 61.7% |
| 4 | MX25 | 4 ライン + chain4 + B-pack + プリフェッチ | 83.15 | 61.9% |
| 5 | MX20 | 4 ライン + chain4 + Bᵀ(転置) | 79.21 | 58.9% |
| 6 | MX18 | 4 ライン + chain4 + プリフェッチ | 79.75 | 59.3% |
| 7 | MX17 | 4 ライン + chain4 + パッキングなし | 78.80 | 58.6% |
| 8 | MX16 | 4 ライン + chain4 + アラインメント | 72.58 | 54.0% |
| 9 | MX15 | 4 ライン + chain3 + B-pack | 62.34 | 46.4% |
| 10 | MX14 | 4 ライン + chain2 + B-pack | 55.76 | 41.5% |
| 11 | MX13 | 2 ライン + chain4 + B-pack | 53.58 | 39.9% |
| 12 | MX12 | 2 ライン + chain3 + B-pack | 50.56 | 37.6% |
| 13 | MX11 | 4 ライン + chain2 + アラインメント | 47.15 | 35.1% |
| 14 | MX08 | 2 ライン + chain4 + BK=128 | 45.04 | 33.5% |
| 15 | MX07 | 2 ライン + chain3 + Bt なし | 43.52 | 32.4% |
| 16 | MX05 | 2 ライン + chain2 + Bt | 41.93 | 31.2% |
| 17 | MX19 | 4 ライン + chain5 + アラインメント | 42.07 | 31.3% |
| 18 | MX06 | 2 ライン + chain1 + プリフェッチ | 42.54 | 31.7% |
| 19 | MX04 | 4 ライン + chain1 + Bt | 40.04 | 29.8% |
| 20 | MX03 | 2 ライン + chain1 + Bt | 39.34 | 29.3% |
| 21 | MX02 | 2 ライン + chain1 + j-block | 37.60 | 28.0% |
| 22 | MX01 | Bt + 2Dtile + 8acc (ベースライン) | 35.16 | 26.2% |
| 23 | MX10 | 4 ライン + chain6 + Bt | 14.26 | 10.6% |
| 24 | MX26 | 8 ライン + chain4 + B-pack | 12.24 | 9.1% |
| 25 | MX28 | 4 ライン + chain4 + dual16 | 13.75 | 10.2% |
| 26 | MX27 | 4 ライン + chain4 + C-in-regs | 9.13 | 6.8% |
| 27 | MX09 | BI=128, BK=256 + chain4 | 8.38 | 6.2% |
| 28 | MX21 | 4 ライン + chain4 + stream stores | 1.24 | 0.9% |
🔍 失敗要因の分析
以下の構成は期待通りの性能を発揮せず、その原因は以下の通りです。
| モデル | テクニック | GFLOPS | 主な原因 |
|---|---|---|---|
| MX21 | 非時限ストア (Stream Stores) | 1.24 | C が読み込み・修正・書き込みされるため、各ストアでキャッシュラインが無効化され、DRAM リロードが頻発します。 |
| MX26 | レジスタに 8 ライン保持 | 12.24 | YMM レジスタ 64 個が必要であり、そのうち 48 個がスパイル(ディスク)されるため、実行時間に支配的です。 |
| MX27 | k-block を通じて C-in-regs | 9.13 | 蓄積子を多数の反復にわたって生かし続け、レジスタ圧力が高まります。 |
| MX09 | BI=128, BK=256 | 8.38 | ワーキングセット(128×256×4 = 128 KB)が L1 を超え、多くのキャッシュミスが発生します。 |
| MX10 | Chain6 (長い連結) | 14.26 | チェーンが長すぎるため、レジスタ不足によって過剰なスパイルが発生します。 |
🧪 検証結果
すべてのモデルを参照実装(従来の ijk ループ)と比較して検証しました。
- 上位 3 つのモデル(MX24, MX22, MX23)は絶対最大誤差が 0.0 で、ビット単位で同一の結果となりました(加算順序が保持されたため)。
- その他のモデルも浮動小数点算術に固有の範囲内(約 1e-6 オーダー)の誤差のみを示し、妥当性を確認しました。
📚 引用表記
本研究成果の研究にご利用の場合は、以下の論文を引用してください。
@article{housl2025gemm, title={85.30 GFLOPS Single-Core FP32 Matrix Multiplication on AMD Zen 3}, author={Housl}, journal={arXiv preprint}, year={2025} }
🤝 コントリビューションとライセンス
- コントリビューション: 改善案、新しいモデル、あるいは他のアーキテクチャへの適応などのご提案をお歓迎いたします。Issue または PR でお送りください。
- ライセンス: MIT ライセンスの下で提供されています。著作権表示と許可を維持する限り、複製・変更・配布が可能です。詳細は
ファイルをご確認ください。LICENSE
📧 著者情報
- 著者: Lucas Lima Freitag
- 所属: フォルネリョ大連邦大学 (Universidade Federal do Rio Grande do Norte - UFRN)
- E メール: freitag.lima@academico.ifrn.edu.br
- ORCID: 0009-0006-8849-5619
最適化を楽しんでください!🚀