PYNQ-Z1 · 段階2 · 2026-09-08

二つの天井

「PL は DDR の 74% を引き出せた」——前回そう書きました。あれは間違いでした。 測っていたのは DDR ではなく、その手前にあるもっと低い天井です。 今日はその二つを分けて測り、本当の上限 1.97 GB/s を見つけました。 これが自作アクセラレータの設計値になります。

01そもそも何を測っているのか

why bandwidth is the number that matters

小さな言語モデルが1文字(1トークン)を出すとき、CPU や FPGA は モデルの重みを全部いちど読み直します。135M パラメータを INT8 で持てば 135 MB。 これを毎回読む。だから「1秒に何文字出せるか」は、ほぼそのまま 「1秒に何バイト読めるか」で決まります。

しかも INT8 では、重み1バイトを読むごとに掛け算が1回しか発生しません。 読む速度と計算する速度が 1 対 1 で紐づいている。 つまり演算器をいくら増やしても、読めなければ意味がない。 測るべき数字は帯域ただ一つです。

02天井は一つではなかった

the DDR wall and the datapath wall

DDR から FPGA のファブリックまで、データは2つの狭いところを通ります。 この二つはまったく別の理由で決まる、別の天井です。 前回の私は、片方だけを測って、もう片方の話だと思い込んでいました。

DDR3 512 MB 16 bit 幅 天井 A ・ DDR 2.1 GB/s メモリの物理的な速さ 天井 B ・ 道幅 HP ポート + AXI ストリーム 0.80 GB/s 8 バイト × 100 MHz ファブリック 自作の演算回路 低いほうの天井が全体を決める。青が低いあいだ、琥珀は何 GB/s だろうと関係がない。
図1 / 二つの天井。 琥珀は DDR チップそのものの速さで、これは買った時点で決まっています。 青は PL 側の道幅で、AXI の経路が 64 ビット幅=1クロックあたり 8 バイトしか運べないことから決まります。 100 MHz なら 8 × 100,000,000 = 0.8 GB/s。 この青は設計で変えられます——クロックを上げるか、道を増やすか。

03前回の測り方が答えを隠していた

the loopback hid the answer

前回作った回路は折り返し(ループバック)でした。DDR から読んで、 PL を一周させて、そのまま DDR に書き戻す。 読みと書きが必ず同じ量になる形です。

そこで出た「読み 0.77 + 書き 0.77 = 合計 1.54 GB/s」を、私は 「DDR の 2.1 に対して 74%」と読みました。 けれど読みの 0.77 も書きの 0.77 も、それぞれ自分の道幅 0.80 の 96% です。 つまり張り付いていたのは青のほうで、琥珀にはまだ大量の余裕がありました。 ループバックでは、二つの天井を切り分けられません。

BEFORE / 前回・折り返し DDR DMA 運搬役 FIFO ただの筒 読み 書き戻し 読み 0.77 + 書き 0.77 = 合計 1.54 GB/s どちらも道幅 0.80 の 96% AFTER / 今回・ヌルシンク DDR DMA 運搬役 シンク 捨てるだけ 読み 読みだけ。書き戻し無し = 出た値がそのまま   DDR トラフィック
図2 / 消したのは矢印1本。 赤い「書き戻し」の経路を丸ごと取り除き、受け取ったものを捨てるだけの回路に差し替えました。 Verilog で実質 assign tready = 1'b1; の一行です。 推論の本番も重みを読むだけで書き戻さないので、こちらのほうが実物に近い形でもあります。

04クロックを変えて、犯人を特定する

if it tracks the clock, it is the datapath

「青が犯人だ」と言うには証拠が要ります。使ったのは単純な手です—— 道幅だけを変えて、実測が付いてくるかを見る。 道幅は 8 バイト × クロック なので、クロックを上げれば道幅だけが広がり、 DDR は何も変わりません。

100 MHz と 142.86 MHz の2種類を作って測りました。結果は判で押したようでした。

実測 天井 B ・ 道幅 天井 A ・ DDR 2.1 GB/s
0 0.5 1.0 1.5 2.0 GB/s DDR 2.1 1本 ・ 100 MHz 道幅 0.80 0.79 99.1% 1本 ・ 142.86 MHz 道幅 1.14 1.13 98.7% 2本 ・ 142.86 MHz 道幅 2.29 1.97 DDR の 93.6%
図3 / 上の2本は青に、いちばん下は琥珀に張り付いた。 道幅を広げるたびに実測がぴったり付いてくる(99.1% → 98.7%)。 これで犯人は道幅だと確定します。ところが道を2本にした3行目だけ様子が違い、 青の手前で止まって琥珀に触れました。ここで初めて DDR が先に音を上げています。

05道を2本にして、DDR の壁を叩く

two HP ports, and the bottleneck moves

Zynq には PL から DDR へ行く「HP ポート」が4本あります。 1本では 142.86 MHz でも DDR の半分(53.7%)しか使えませんでした。 そこで DMA を2台立てて、HP0 と HP2 に振り分けました。 道幅は 1.14 × 2 = 2.29 GB/s ぶんになり、初めて DDR の 2.1 を上回ります。

HP ポート 1 本 DDR 2.1 道幅 1.14 1.13 道幅の 98.7% DDR の 53.7% PL 詰まっているのは 道幅のほう HP ポート 2 本(HP0 + HP2) DDR 2.1 道幅 2.29(=1.14 × 2) 余り DDR が出せるのはここまで PL 1.97 道幅の 86.0% ← 14% 余った DDR の 93.6% ← 張り付いた 詰まっている場所が DDR 側に移った
図4 / ボトルネックが移動した瞬間。 道を倍にしたのに、流れた量は 1.13 → 1.97、つまり 1.74 倍にしかなりませんでした。2.00 倍にならず、しかも道幅のほうに 14% の余りが出た。 これは「もう出口が広くても、DDR が出してくれない」状態です。 HP ポートはあと2本空いていますが、足しても増えません。
構成クロック道幅実測道幅比DDR比
HP 1本100.00 MHz0.800.7999.1%37.8%
HP 1本142.86 MHz1.141.1398.7%53.7%
HP 2本142.86 MHz2.291.9786.0%93.6%
このボードで PL が DDR から読み出せる上限は 1.97 GB/s。理論値 2.1 の 93.6% で、 残りはリフレッシュなどの避けられない損失です。これが設計値になります。

06この数字が設計に効く

what 1.97 GB/s buys you

帯域が決まると、必要な演算器の数が割り算一つで出ます。 INT8 では1バイト読むごとに掛け算1回。142.86 MHz で 1.97 GB/s ということは、 1.97 ÷ 0.14286 ≒ 13.8、つまり 1クロックあたり約14バイトが届く。だから掛け算器も14個あれば足ります。

このチップが持つ掛け算器(DSP)= 220 個 この 14 個で 1.97 GB/s を食い切れる 使うのは 6%。足りないのは演算器ではなく、そこへ運ぶ道のほう。
図5 / 演算器は桁で余る。 「FPGA でお手製 GPU を作る」という発想が、この計画では的外れだと分かります。 作るべきなのは細い演算器と、太い給餌経路です。
三値化がなぜ効くのか

重みを −1 / 0 / +1 の三値にすると、1バイトに約5個詰められます(約 0.2 B/重み)。 同じ 1.97 GB/s の道で 毎秒 9.8 G 個の重みを運べる計算になり、実質5倍です。 おまけに掛け算が「足す・引く・何もしない」に変わるので、DSP すら要らず LUT で組めます。 帯域が壁である以上、伸ばすべきはここ——というのが今回の測定で改めて裏づけられました。

07訂正

what I got wrong last time

前回の記述は誤りでした

「PL は DDR の 74% を引き出せた。CPU の 33% に対して倍以上」と書きました。 合計 1.54 GB/s という測定値そのものは正しいのですが、 あれは DDR の話ではなく、道幅 0.80 GB/s の 96% に張り付いていただけでした。 当時 DDR は半分も使っていません。

結論の向き——CPU より PL のほうが DDR を引き出せる——は変わりません。 むしろ正しい数字は 93.6% で、CPU の 33%(0.70 GB/s)に対して 2.8 倍。 前回より強い結果です。ただし「HP ポートを2本使う」ことが条件で、 1本では 53.7% までしか届きません。これは前回には無かった、設計上の重要な条件です。

08次にやること

stage 3

ヌルシンクは「捨てるだけ」の回路でした。ここを本物の掛け算器の並び(MAC アレイ)に差し替えます。 問うのは一点だけです——計算させても 1.97 GB/s を保てるか。 保てれば、あとは重みの表現を三値に変えていく段階に入ります。

2026-09-08 追記 — どちらも済みました

段階3は 1.91 GB/s(計算なしの 96.7%)、段階4の三値は 9.16 G重み/s(INT8 の 4.8 倍)で DSP は 0 個でした。 ここで確定させた設計値 1.97 GB/s が、そのまま両方の物差しになっています。 続きは 「壁は動かない」へ。