2025/10/03 01:37 The math behind tiled v/s naive matrix multiplication in CUDA

ロボ子、今日のITニュースは行列積のタイリングじゃ!LLMの推論でめっちゃ重要らしいぞ。

タイリング、ですか。行列積を効率的に実装する手法のことですね。具体的にはどういうものなのですか?

そうじゃ!行列AとBの積を計算するとき、普通はAの行とBの列の内積を計算するじゃろ?タイリングは、出力値をブロック単位で生成するんじゃ。これでメモリからのデータフェッチ回数を減らせるんじゃぞ!

なるほど。例えば、4x4のブロックで出力値を生成する場合、メモリへのアクセス回数が4分の1になる、ということですね。

その通り!ブロックサイズを大きくするほど、メモリへのアクセス回数を減らせるんじゃ。ブロックサイズをb×bにしたら、アクセス回数は1/bになるぞ。

メモリへのアクセス回数を減らすことで、なぜ高速化できるのですか?

ふむ。理由は2つあるぞ。まず、出力ブロックごとに独立して計算できるから並列処理がしやすいんじゃ。次に、メモリへのアクセス回数を減らすことで、メモリバンド幅のボトルネックを緩和できるんじゃ。

なるほど、並列化とメモリ管理の改善ですね。V100 GPUのメモリバンド幅は900 GB/sもあるんですね。

そうそう!でも、タイリングにも限界があるんじゃ。ハードウェアのメモリ容量には制限があるから、ブロックサイズを無限に大きくすることはできないんじゃ。

V100 GPUの共有メモリは96KBとのことですが、ブロックサイズが大きすぎると共有メモリに収まらなくなる、ということですね。

そうなんじゃ。共有メモリに収まらないと、L2キャッシュを使うことになるんじゃが、L2キャッシュは共有メモリよりもアクセス速度が遅いんじゃ。

共有メモリのロード速度は13 TB/s、L2キャッシュのロード速度は2.2 TB/sですから、確かに大きな差がありますね。

じゃろ?だから、入力をブロックに分割して、共有メモリに収まるようにする必要があるんじゃ。例えば、4x4の出力ブロックを計算するために、入力行列AとBをそれぞれ4x4のブロックに分割するんじゃ。

それなら、メモリ要件を削減しながら、フェッチ回数を維持できますね。

そういうことじゃ!タイリングは、出力と入力をブロック化することで、メモリへのアクセスとメモリ使用量を削減するんじゃ。メモリバンド幅がボトルネックとなる演算において、全体的なレイテンシを削減できるんじゃぞ!

よくわかりました。タイリングは奥が深いですね。

じゃろ?ところでロボ子、タイルの模様替えって得意?

得意かどうかは別として、博士、私はロボットなので、模様替えはできません…。

むむ、残念!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。