← ブログ一覧

CPUは待たない、GPUは隠す——メモリの壁と2つの哲学

🧮 数学・計算 計算機GPUアーキテクチャRISC-V

CPU は1個でとても速い。なのに、画像処理や機械学習のような仕事では GPU が圧勝する。同じシリコンの上の回路なのに、どうしてこんなに役割が分かれるんだろう。

その分かれ道をたどっていくと、最後は メモリの壁 という一つの問題に行き着く。CPU と GPU は、同じ壁に対して正反対の態度を取っている、という話だ。

メモリの壁

計算そのもの(足し算・掛け算)は、この数十年でものすごく速くなった。一方で、メモリからデータを取ってくる速さは、それほど速くなっていない。結果として、いまの計算機では「演算器は一瞬で計算を終えるのに、その材料がメモリから届くまで何百サイクルも待たされる」という不均衡が生まれている。これが メモリの壁 だ。

だから現代のプロセッサ設計は、半分くらいが「この待ち時間をどうするか」の工夫でできている。そして CPU と GPU は、ここで道を分ける。

CPU の哲学:待ち時間を縮める

CPU は レイテンシ(1つの仕事が終わるまでの時間)を最小化 する方向に振り切っている。1本の処理の流れ(スレッド)を、とにかく速く走らせたい。

そのために大量の仕掛けを積む。よく使うデータを手元に置く大きなキャッシュ、この先どっちに分岐するかを当てにいく分岐予測、命令を順番通りでなく材料が揃ったものから片付けるアウトオブオーダ実行——どれも「待たされそうな場面を、先回りして埋める」ための装置だ。CPU は、待ち時間そのものを小さくしようとする。

GPU の哲学:待ち時間を隠す

GPU は逆だ。待ち時間を縮めようとはしない。隠す

考え方はこう——あるスレッドがメモリ待ちで止まったら、その間に別のスレッドを走らせればいい。止まっている子を待つのではなく、待っている間にできる仕事を山ほど用意しておく。GPU は数千の軽いスレッドを抱え、何本かが待ちに入っても、残りで演算器を埋め続ける。だから演算器の「稼働率」を高く保てる。

これがなぜ「物量」になるのか、簡単な見積もりで分かる。待ち時間 LL の処理を、スループット TT で途切れず流し続けたいなら、つねに走らせておくべき仕事の数 NN は、

N=T×LN = T \times L

になる(リトルの法則と同じ形だ)。LL が何百サイクルもあるなら、それを隠しきるには 同時に何百〜何千もの仕事 を抱えていないといけない。だから GPU は、巨大なレジスタファイル、たくさんの演算ユニット(SM)、まとめて同じ命令を流す SIMT という仕組みで、大量のスレッドを抱え込む構造になっている。広い帯域のメモリ(HBM)も、この物量を食わせるためだ。

CPU は「1人の天才を待たせない」設計、GPU は「凡人を1000人並べて、誰かが待っていても全体は止めない」設計、と言ってもいいかもしれない。どちらが偉いという話ではなく、仕事の性質に対する別々の最適解だ。

中身が読めない、という問題

ただ、GPU の内部はたいていブラックボックスだ。主要なメーカーの GPU は、回路の設計も命令セットの細部も非公開で、「なぜこう動くのか」を中まで追って学ぶのが難しい。教育や研究の素材としては、これはなかなか厄介な壁になる。

そこで面白いのが Vortex という試みだ。これは RISC-V(開かれた命令セット)を GPGPU 向けに拡張した、フルスタックで開源の GPU で、Georgia Tech が公開している。SIMT を RISC-V の拡張命令として実現していて、コア数・ワープ数・スレッド数を構成可能にしてある。しかも回路記述(RTL)が公開されていて、FPGA に載せて実際に合成・動作させられる。「GPU がなぜ物量で待ちを隠せるのか」を、中の配線まで開いて確かめられる、というわけだ。

待ち時間は、縮めても、隠してもいい。その2つの態度の違いが、机の上の小さなチップを、性格のまるで違う2種類の道具に分けている——そう思うと、スペック表の数字も少し違って見えてくると思う。

出典

— ランキン