第96話のCPU laneがWAIT_EVENTから戻った。
distributorには、千枚のwork cardが積まれている。
イトは一枚目をCPU laneへ置いた。
二枚目も。
そのまま千枚すべてを、同じ入口へ並べた。
「CPUなら、どんなinstructionも扱えるんだよね」
preview clockが回る。
work items 1000
route CPU lane 1
estimated finish tick 104
handoff deadline tick 30
deadline over +74
commit 0
千枚の後ろ九百九十九枚が、動かない。
「一番何でもできる場所へまとめたのに」
千件は、同じ仕事ではなかった
Picoが、カードへ三色のinspection lightを当てた。
branchy control / callbacks 48
same pixel transform 768
supported neural inference 184
total 1000
CPUへ渡したのは、千件の同じ仕事ではない。
条件を読み分けるcontrol work。
同じ変換を別々のpixelへかけるwork。
対応済みmodelのneural inference。
三つが混ざったbatchだった。
イト
CPU、GPU、NPUのどれが一番強いかを決めればいいんじゃないの?
ユイ
先に、仕事の形を分ける必要がありそうです
ピコ
core数やTOPSの数字だけでは、違う種類の仕事を同じ物差しで比べられないよ
Picoはrouteを選ばない。
千件の内訳と、各workが要求するoperationだけを照らした。
CPUは「一人で順番に処理する装置」ではない
CPUはgeneral-purposeな処理を担う。
OSやapplicationのcontrol flow。
分岐の多い処理。
さまざまなoperationを切り替える仕事。
低いlatencyを求める小さな仕事や、GPU / NPUへworkを渡す調整も受け持てる。
でもCPUを「一coreで一件ずつしか動けない」と決めない。
real CPUには複数core、hardware thread、vector instructionがあり、並列に進められる仕事もある。
今回遅れたのはCPU一般の限界ではない。
イトがclosed fixtureのCPU lane 1へ千件を一列に積み、work shapeごとのrouteを調べなかったからだ。
GPUは、同形の大量workでthroughputを出しやすい
GPUは、多数のthreadへworkを分けて進められる。
たとえば別々のpixelへ同じtransformをかけるように、同じkernelを多くのdataへ適用できる仕事と相性がよい。
ただし「一千laneが、一千の違う仕事を完全に独立して同時実行する」と固定しない。
GPUの実行modelでは、threadをgroupにまとめ、共通のinstructionを進める設計がある。
同じgroup内でdata-dependent branchが分かれると、片方を進める間、別のlaneが休むことがある。
これをbranch divergenceとして調べる。
hostからkernelをlaunchする時間や、CPU側とGPU側の間でdataを移す時間もある。
workが少ない、分岐が多い、data movementの方が重い場合は、lane数が多いだけでは速くならない。
NPUは、対応するneural networkの計算を効率化する
NPUは、deep-learning modelで使う計算を進めるためのspecialized acceleratorだ。
対応するmodelを端末上でinferenceするとき、latencyやenergy consumptionを抑える設計に使われる。
でも「AIと呼ぶ処理は全部NPUへ入る」わけではない。
model、operator、data type、runtimeがNPUに対応しているかを先に確認する。
未対応部分はCPU / GPUへfallbackすることがある。
前処理、後処理、application controlまで含めると、三者が一つのtaskを分担する場合もある。
端末、model、runtime、設定が変われば、速さや消費電力も変わる。
製品名だけで決めず、target deviceで測る。
よくある誤解:数字が最大のprocessorへ全部送れば速い
core数、clock、FLOPS、TOPS、memory bandwidth。
数字は重要だ。
ただし定義や測定条件、対象operationが違う数字を、そのまま一列へ並べない。
大きなpeak値があっても、softwareが使えなければ実workは流れない。
data transfer、launch、synchronization、fallbackの時間を除いた数字だけで、application全体の速さは決まらない。
今回の目標は「最大specの部屋を選ぶ」ではない。
correct outputs 1000 / 1000
finish deadline tick 30 or earlier
energy budget 20 units or less
unsupported operation 0
このtickとenergy unitはlab fixtureの比較値だ。
real productのbenchmarkではない。
handoffまで残り18秒
preview clockのdeadline overは、まだ+74。
残り十八秒。
source workはread-only。
全千件のoutputを一度だけjoinする。
operationが未対応なら、勝手に別processorへfallbackせず停止する。
各routeのstart / finish、transfer、error、energyをtraceへ残す。
イトはthree-way distributorの前へ立った。
イト
A。何でも扱えるCPU lane 1へ、千件をそのまま一列で流す
イト
B。lane数の多いGPUへ、controlもpixelもneural inferenceも全部流す
イト
C。work shapeと対応operationを確認し、controlはCPU、same pixelはGPU、対応済みinferenceはNPUへ分ける
Aは正しくてもdeadlineを越える。
Bはcontrol workのhost callbackを往復させ、同じkernelへそろわない。
Cにはdispatchとjoinの手間が増える。
それでもrouteごとの目的と停止条件を検査できる。
イトがone-size-fits-all funnelを閉じ、三つのrouteを開いた
イトは左手で、千件を一室へ落とすred funnelを閉じた。
右手で、shape scannerのthree-way guardを開く。
branchy cardをsmall blue control routeへ置いた。
同形tileをwide cyan parallel routeへ並べた。
対応済みmodel tileをcompact amber neural routeへ通した。

Picoはshape scannerの境界だけを照らす。
card、gate、route、join leverには触れない。
三routeが、千件を一つのresultへ戻した
イトはCPU routeだけをsingle-stepした。
route CPU control
items 48
branch / callback supported 48
finish tick 6
energy units 4
errors 0
次にGPU routeをlaunchする。
route GPU pixel transform
items 768
same kernel 768
transfer + launch ticks 2
compute finish tick 8
divergent items 0
energy units 7
errors 0
NPU routeでは、runtimeのsupport listとmodel hashを先に照合した。
route NPU neural inference
items 184
required operators supported
fallback requested 0
finish tick 7
energy units 4
errors 0
最後に、イトがjoin leverを引く。
joined outputs 1000 / 1000
wall finish tick 11
energy total 15
unsupported operation 0
source work changed 0
deadlineまで十九tick残った。
「一番強い部屋を当てたんじゃない。三つの仕事に合うrouteを作ったんだ」
速さだけでなく、配るcostも残った
一室にまとめるより、dispatch tableは複雑になった。
三つのruntimeを検査する必要もある。
data copyとjoinが増えれば、分けた方が遅くなる場合もある。
model updateでNPUのunsupported operatorが増えたら、同じrouteを使い回せない。
だからCPU / GPU / NPUという名前だけを保存しない。
work shape
supported operation / runtime
data location and transfer
latency / throughput target
energy target
measured result on target device
この六つを、dispatch decisionと一緒に残す。
GPU wallへ、掛け算の板が届いた
三routeがWAIT_EVENTへ入る。
その直後、奥のtraining dockから巨大なwork boardが届いた。
同じ形のmultiply-and-add cellが、縦横に並んでいる。
matrix cells many
independent output rows many
current CPU test lane 1
GPU route ready
イトはさっきの成功を見て、すぐGPUへ投げようとした。
でも今度は、入力dataの置き方と、threadへ分ける単位をまだ決めていない。
同じ形の大量workでも、並べ方が悪ければlaneは待つ。
イトはlaunch leverの手前で止まり、掛け算の板を小さなtileへ区切った。
次回、ピコルート第98話。
イトは、壁一面の掛け算を一列へ積んだ|GPUはなぜAI計算に向いている?

