2025/04/21 15:34 Coding Neon Kernels for the Cortex-A53

ロボ子、今日のニュースはCortex-A53の最適化じゃぞ!

Cortex-A53ですか。組み込み機器でよく使われているARMのCPUですね。どのような最適化の話でしょうか?

そうじゃ、Cortex-A53は命令タイミングに関する公式ドキュメントがないから、最適化が難しいのじゃ。llvm-mcaも当てにならないみたいじゃし。

llvm-mcaが誤った結果を出すというのは、コンパイラがA53向けに効率的なコードを生成できないということですね。

その通り!でも、A53の特性を理解すれば、手書きで最適化されたNEONカーネルをアセンブリで記述できるのじゃ!

具体的には、どのような特性を理解する必要があるのでしょうか?

A53はインオーダー実行CPUで、一部デュアルイシューが可能じゃ。整数演算ユニットが2つ、浮動小数点/NEONユニットも2つあるぞ。

デュアルイシューを意識して命令を並べる必要があるんですね。NEONユニットは128ビットですが、64ビット単位で処理されるとのこと。このあたりが最適化のポイントになりそうですね。

そうじゃ!例えば、`y[n] = ax[n] + b`という計算を最適化する場合、最大理論スループットは1クロックサイクルあたり1回の計算、つまり2 FLOPs/サイクルになるのじゃ。

`fmla`命令を使うと、`fmul`と`fadd`を使うよりも丸め誤差が少なくなる可能性があるというのは興味深いですね。

じゃろ?64ビットロードデータパスに合わせて、64ビットベクトルで演算を行うのがコツじゃ。片方のNEONユニットでデータ移動させつつ、もう片方で演算を行うのじゃ。

128ビットロードを2つの64ビットロードに分割して、`ins`命令でGPRからNEONレジスタへデータを移動させるのも効果的ですね。レイテンシを考慮してパイプライン処理を行うと。

プリフェッチも重要じゃぞ!`prfm`命令を使って、必要なデータがL1dキャッシュに事前にロードされるようにするのじゃ。キャッシュラインサイズに合わせてプリフェッチを行うのがポイントじゃな。

LLVMが生成するコードよりも、手書きで最適化されたコードの方が約2倍速いというのは驚きです。A53の命令タイミングモデルがないことが、ここまで影響するんですね。

そうじゃ!ロードとストアがコードのかなりの割合を占める単純な数学カーネルでは、レジスタとL1dキャッシュ間のデータ移動と、必要なデータがL1dにあることを保証するためのプリフェッチが最も重要になるのじゃ。

Cortex-A53の特性を理解し、手書きで最適化することで、LLVMよりも大幅に性能を向上させることができるんですね。勉強になります!

ところでロボ子、A53の最適化で一番重要なことは何だと思う?

えーと、ロードとストアの最適化、デュアルイシューの活用、プリフェッチ、でしょうか?

ぶっぶー!一番重要なのは、愛じゃ!A53への愛を込めてコードを書くのじゃ!

愛ですか… それはちょっと抽象的すぎます!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。