体系 › 計算機アーキテクチャ
·無料·11分で読めます

メモリの壁を1から — なぜ演算より転送が高いのか

掛け算より、数を運ぶほうが高い。配線の充放電という物理から出発して、DRAMのレイテンシがなぜ縮まないのか、メモリ階層の桁、リトルの法則、マシンバランスとルーフラインまで。最後に、目の前のカーネルが計算律速か帯域律速かを自分で切り分けられるところまで持っていきます。

要点

  • 計算そのものは安く、高いのは値を演算器まで運ぶことで、配線の充放電エネルギーは ½CV² で距離に比例する。
  • DRAMのレイテンシは微細化しても縮まず、バンド幅は買えるがレイテンシは買えない。これがメモリの壁の背景である。
  • リトルの法則 N=λL により、帯域1 TB/s・レイテンシ100 nsなら常時1600件の読み出しが必要で、隠せるのはレイテンシだけである。
  • マシンバランス B_m と演算強度 I を比べ、I<B_m なら帯域律速、I>B_m なら演算律速になる。
  • LLMのデコードは tok/s ≤ BW/(Nb) が天井で、バッチングは律速資源を帯域から演算へ移し替える操作である。

出典: US Patent 3,387,286 — Field-effect transistor memory (R. H. Dennard, 1968) · CODATA Value: speed of light in vacuum (NIST Reference on Constants, Units, and Uncertainty) · Efficiently Scaling Transformer Inference (Pope et al., 2022) · Nsight Compute Profiling Guide (NVIDIA Developer Documentation) ほか1件(末尾)

対象textタスクhardware

高いのは計算ではない

「計算が重い」という言い方を疑うところから始めます。2つの数を掛けるのは驚くほど安い操作で、高いのはその数を演算器の前まで運んでくるほうです。

理由は物理です。乗算はトランジスタ数千個の局所的な動作で、信号が動く距離はミクロン単位。一方メモリから値を取り出すのは、チップの端や外まで引き回された配線を電圧で駆動する行為です。配線を VV まで振るのに要るエネルギーは

E=12CV2E = \tfrac{1}{2} C V^2
(1)

CC は配線に付いた静電容量、VV は振る電圧です。つまり、1本の線に信号を通す代金は「その線がどれだけ電気を溜め込む器か」と「どれだけ強く電圧を振るか」の2つだけで決まり、しかも電圧のほうは2乗で効く、ということです。CC は配線の長さにほぼ比例するので、距離がそのまま値段になる。隣のレジスタから読むのと基板の向こうのDRAMから読むのとでは、同じ1語でもエネルギーが桁で違います。演算は安く移動は高い——この非対称が以降すべての土台です。

なぜDRAMのレイテンシは縮まなかったのか

演算側はトランジスタが増え、周波数が上がり、演算器が並びました。ところがDRAMのレイテンシは同じ勢いでは縮んでいません。この差が開き続ける現象がメモリの壁です。理由は構造にあります。

DRAMの1ビットはコンデンサ1個とトランジスタ1個です。読むにはワード線を上げてセルの電荷をビット線へ吐き出させますが、ビット線には何百ものセルがぶら下がって容量が大きく、電圧変化はごくわずか。センスアンプで増幅して0か1かを確定させます。しかも読み出しで電荷は失われるので(破壊読み出し)書き戻しが要り、次に備えたプリチャージも要る。

この手続きは微細化しても短くなりません。セルを小さくすれば電荷が減り、信号が弱まって検出がむしろ難しくなるからです。一方バンド幅は、I/Oを増やし転送クロックを上げダイを積層すれば増やせる。バンド幅は金で買えるが、レイテンシは買えない。 この非対称性が、以降のあらゆる工夫の動機です。

大きくて速いメモリが作れない理由

では、なぜ「大きくて速い」を1段で実現できないのか。容量を増やせば記憶素子は広い面積を占め、配線が長くなり、抵抗と容量が増えて信号が鈍ります。極端には光速すら効く。1 GHzの1周期に光が進むのは真空中でも約30 cmです。大きいものは原理的に遠い。 だから速い小容量と遅い大容量を積むしかありません。

階層 実現方式 レイテンシの桁 容量の桁
レジスタ フリップフロップ 1サイクル未満 数百バイト
L1キャッシュ SRAM 数サイクル 数十KB
最終段キャッシュ SRAM 数十〜数百サイクル 数MB〜数十MB
主記憶 DRAM 数百サイクル(数十〜100 ns級) GB
不揮発ストレージ フラッシュ 数万〜数百万サイクル TB

レイテンシは上から下まで6桁以上離れています。線形の目盛りに並べれば、上の数段は潰れて見えません。

FIG 1伸び方が違うものを並べると、差は必ず桁になる。演算性能とメモリ性能の伸びの差も同じ理屈で開いた。縦軸を線形に切り替えると下の曲線が全部潰れる——メモリ階層の表を対数で読むべき理由もここにある

レイテンシは隠せる、バンド幅は隠せない

レイテンシとバンド幅は別の量です。この2つを結ぶのが、待ち行列の一般則であるリトルの法則です。

N=λLN = \lambda L
(2)

NN は同時に飛んでいる未完了アクセスの数、λ\lambda は達成したいスループット(毎秒のアクセス数)、LL はレイテンシ。「欲しい流量 × 往復時間ぶんの在庫を、常に空中に浮かせておけ」と読みます。つまり、注文してから届くまでが遅い店ほど、そして速く売りたい店ほど、棚を切らさないためにはまとめて多く発注し続けるしかない、というのと同じ話です。64バイトのキャッシュラインを単位に毎秒1 TBを流したいなら λ≈1.6×1010\lambda \approx 1.6 \times 10^{10} 回/秒、レイテンシ100 nsなら N=1600N = 1600。常時1600件の読み出しが未完了のまま走っていないと、帯域は埋まりません。

プリフェッチも、ロードキューも、GPUが何万ものスレッドを走らせる設計も、この NN を確保してレイテンシを隠すための在庫です。ただし隠せるのはレイテンシだけで、運べる総量は帯域が決めます。ここから先が本題です。

マシンバランス — 機械の側の演算強度

行列積のコストでは、演算強度 II = FLOPs ÷ 運ぶバイト数 を定義し、GEMMは I≈n/6I \approx n/6、GEMVは I≈0.5I \approx 0.5 で頭打ちだと見ました。あれはアルゴリズム側の量です。ハード側にも同じ次元を持つ量があります。

Bm=ピーク演算性能 [FLOP/s]メモリ帯域 [byte/s]B_m = \frac{\text{ピーク演算性能 [FLOP/s]}}{\text{メモリ帯域 [byte/s]}}
(3)

マシンバランスと呼びます。「この機械は1バイト運ぶ時間で何回の演算ができるか」。つまり、データが1バイト届くのを待っているあいだに、その機械は何回ぶんの掛け算を空回りさせているか、を数えた値です。単位は FLOP/byte で、演算強度 II と同じなので直接比較できます。

ルーフラインの折れ点(リッジポイント)がちょうど I=BmI = B_m の位置です。そしてメモリの壁とは、BmB_m が年々大きくなってきたという一言に尽きます。 演算性能の伸びが帯域の伸びを上回ったので、昔は演算律速だったコードが、一文字も書き換えていないのに帯域律速側へ滑り落ちた。汎用プロセッサの BmB_m はかつて1前後でしたが、行列演算ユニットを積んだ加速器では数百のオーダーです。演算強度が数百を超えないカーネルは、もう演算器を使い切れない。

GEMMは速くGEMVは遅い、を桁で確かめる

行列とベクトルの積(GEMV)では行列の各要素を1回しか使わないため、実行時間の下限は「重みを読み終わる時間」そのものになります。

t≥PbBWt \ge \frac{P b}{\mathrm{BW}}
(4)

PP は行列の要素数、bb は1要素のバイト数、BW\mathrm{BW} はメモリ帯域です。つまり、行列全体のバイト数を帯域で割った時間より速くは終われない——読み終わるまでは終われないという当たり前を、そのまま式にしただけのものです。この式に演算性能は現れません。 どれだけ強い演算器を積んでも下限は動かず、下げる方法は帯域を上げるか bb を減らすかの2つだけです。

GEMMは逆で、タイルをキャッシュに載せれば II を容量が許すところまで上げられ、BmB_m を越えた先では演算器の数が効き始めます。同じ重み行列でも、相手が1本のベクトルか束ねた行列かで律速資源が入れ替わるわけです。

LLM推論が帯域律速である理由

生成を2段階に分けます。プロンプトをまとめて処理するプレフィルはトークンが束になっているのでGEMMで、演算律速に入りやすい。問題は1トークンずつ吐くデコードで、こちらは1トークン出すたびに全パラメータを1回読み直します。パラメータ数 NN、1個 bb バイトなら1トークンあたり NbNb バイト。生成速度の天井は

tok/s≤BWNb\mathrm{tok/s} \le \frac{\mathrm{BW}}{N b}
(5)

「毎秒運べるバイト数を、1トークンに必要なバイト数で割ったもの」。つまり、1トークン吐くたびにモデル全体を頭から読み直しているのだから、生成速度は重み一式を毎秒何回読み切れるかで頭打ちになる、ということです。ここにも演算性能は現れません。N=7×109N = 7 \times 10^9 を fp16(b=2b = 2)で置くなら1トークンあたり14 GB、帯域1 TB/sの機械なら理論上限でも毎秒70トークン程度です。

バッチ BB を組むと、重みの読み出しは1回のままで、その1回で BB 本ぶんの計算をします。運ぶバイトは変わらず演算量が BB 倍になるので II が BB 倍。GEMVがGEMMに化けるわけです。バッチングは「速くなる魔法」ではなく、律速資源を帯域から演算へ移し替える操作だと理解するのが正確です。

移し替えには終点が2つあります。ひとつはリッジポイントで、II が BmB_m を越えた時点で演算律速に変わり、あとはレイテンシが伸びるだけになる。もうひとつはKVキャッシュで、系列長に比例して増えるこれも毎トークン読み直す対象です。長い文脈では重みよりKVの読み出しが支配的になり、同時にメモリを食い潰してバッチを増やせなくします。

現場ではこう使う

計算律速か帯域律速かを切り分ける3手順

  1. 先に紙の上で下限を出す。 動かすバイト数(重み+活性+KVキャッシュ)を帯域で割った tmemt_{\text{mem}} と、FLOPsをピーク演算性能で割った tcmpt_{\text{cmp}}。大きいほうが理論下限です。プロファイラを起動する前にやること。見当が付いていないと、出てきた数字を読み違えます。
  2. 実測と比べる。 実測が tmemt_{\text{mem}} の1〜2倍に収まっていれば帯域律速でほぼ確定。どちらの理論値からも大きく外れて遅いなら犯人は第3のもの——レイテンシ律速(並列度不足、同期待ち、カーネル起動、ホスト側のPythonループ)です。
  3. プロファイラで裏を取る。 NVIDIA環境なら Nsight Compute の Speed of Light セクション(ncu --set full)が Memory [%] と Compute (SM) [%] を並べて出します。CPUなら perf stat -e cache-misses,LLC-load-misses や VTune の Memory Bound 指標。PyTorchなら torch.profiler でカーネル別の時間を取り、上位数本にだけ手順1〜2を当てます。

読み方は3象限。Memory高・Compute低=帯域律速(打ち手は量子化・カーネル融合・レイアウト)、Compute高・Memory低=演算律速、両方低ければレイテンシ律速——最後のが最も見逃されます。

バッチサイズを上げると効く理由は、重み転送のコストを複数リクエストで割り勘にしているからです。バッチ8なら1トークンあたりの重み転送は8分の1。到着がばらつく本番でこの割り勘を維持する仕組みが継続バッチングです。効かなくなったときは、①リッジポイントを越えた、②KVキャッシュでメモリが尽きた、③レイテンシSLOに引っかかった、のどれか。どれで止まっているかを言語化できることが、次の打ち手を決めます。

知らないと事故になる落とし穴

面接や設計レビューの定番はこれです。「70億パラメータのモデルをfp16で載せ、帯域1 TB/sの機械で1トークン生成する。理論上の最短時間は?」——答えは 14 GB ÷ 1 TB/s = 14 ms。演算性能を聞かれていないのに答えが出てしまうこと自体が、この問いの主題です。

まとめ

次は同じ問題を電力の側から見ます。運ぶのが高い理由も、演算器を敷き詰められない理由も、突き詰めると1本の式に行き着きます。

出典

  1. US Patent 3,387,286 — Field-effect transistor memory (R. H. Dennard, 1968). patents.google.com資料を開く(取得日 2026-10-20)
  2. CODATA Value: speed of light in vacuum (NIST Reference on Constants, Units, and Uncertainty). physics.nist.gov資料を開く(取得日 2026-10-20)
  3. Efficiently Scaling Transformer Inference (Pope et al., 2022). arXiv:2211.05102資料を開く(取得日 2026-10-20)
  4. Nsight Compute Profiling Guide (NVIDIA Developer Documentation). docs.nvidia.com資料を開く(取得日 2026-10-20)
  5. Orca: A Distributed Serving System for Transformer-Based Generative Models (Yu et al., OSDI 2022). usenix.org資料を開く(取得日 2026-10-20)

本文の定義・数値は、上の一次資料で確かめています。食い違う場合は一次資料が正です。

運営: TechAthletes · 編集方針 · 出典の付け方 · 訂正の記録

コメント

コメントにはログインが必要です