AI・量子・未来技術編 / 第96話

第96話:イトは、下書き数「10」を命令口へ入れかけた|CPUは何を実行する?

ピコルート第96話。二進数10を命令口へ入れたら、2ではなくqueue消去と読まれた。data、instruction、program counter、CPUの実行順を分けます。

コンピューター工房命令処理CPU取出・解読・実行・保存10分更新

第95話で、two-bit data 10はdraft count 2へ戻った。

でもrestore carrierは動かない。

data decoded          2
operation selected    none
instruction started  0

イトはblue data cardを持ち上げた。

「これをinstruction slotへ入れれば、二件を運ぶって分かるかな」

red bridgeへ近づける。

toy decoderのpreview lampが点いた。

input context       instruction
raw pattern         10
toy opcode          CLEAR_TEST_QUEUE
commit              0

count railでは2だった10が、instruction railではqueue clearへ変わった。

同じbits。

違う読み方。

イトの指が止まった。

「数字を入れたのに、命令として読まれた」

bitsだけでは、dataかinstructionか決まらない

CPUが扱うinstructionもdataも、下ではbitsとして表せる。

bitsの見た目だけで、片方を自動的にinstructionと決めるわけではない。

どこからinstructionをfetchするか。

どのinstruction set architecture、ISAでdecodeするか。

どのbitsをoperationやoperandとして読むか。

programとexecution environmentの約束が必要だ。

今回のtoy ISAでは、instruction slotの10をCLEAR_TEST_QUEUEへ割り当てている。

この対応はlab fixtureだけの約束で、real CPUに共通のopcodeではない。

イト

10だから2、とは限らない。どのdecoderへ入ったかで意味が変わるんだ

ユイ

data railのschemaと、instruction railのISAは別の読み方なんですね

マコト

raw bitsだけで高い階層の目的まで決めないことだね

Picoはcardを差し替えない。

data holder、instruction memory、decoderを三つのinspection lightで分けた。

program counterは、次に読むinstructionを指す

CPUには、次に処理するinstructionの位置を追うstateがある。

ここではprogram counter、PCと呼ぶ。

simple fixtureの流れはこうだ。

PC -> instruction fetch -> decode -> operand read -> execute
   -> architectural state update -> next PC

instruction fetchは、PC / control flowが選んだ位置からencoded instructionを取る。

decodeは、ISAに従ってoperationとoperand指定を読む。

load instructionならdataを読むことがある。

store instructionならresultを指定先へ書くことがある。

branchやjumpなら、next PCが順番どおりの次位置ではなく変わることがある。

CPUはmemoryにあるすべてのbitsを、端から自動実行するわけではない。

control flowがinstructionとしてfetchしたものを処理する。

fetch・decode・executeは、四人の固定係ではない

fetch → decode → execute → state updateは、仕組みを追うconceptual modelとして役に立つ。

ただしすべてのCPUが、四つの独立した台を一instructionずつ直列に通すわけではない。

real implementationでは複数instructionのstageをoverlapさせるpipelineがある。

先のinstructionを予測してfetchすることもある。

内部ではout-of-orderに進め、ISAから見える結果を正しい順序へ確定する設計もある。

cache hit / miss、branch、interrupt、exceptionによって進み方も変わる。

だからkey一回が必ず何instruction、必ず何cycleとは固定しない。

application、OS、input method、current state、hardwareで変わる。

この記事では、見える因果をsingle-stepできるclosed toy CPUだけを使う。

よくある誤解:電源中のCPUは、命令を休まず流し続ける

実行するworkがある間、CPUはinstructionを進める。

でも「電源が入っていれば、全coreが常に同じ速さで命令を実行し続ける」とは限らない。

OSやfirmwareはidle loopやwait operationを使える。

architectureには、interruptなどのeventを待つinstructionがある場合もある。

coreをstall、idle、sleep、low-power stateへ移すか、waitをhintとして扱うかはarchitecture / implementation / power managementで違う。

interruptやeventで再開する場合もある。

今回のtoy fixtureではWAIT_EVENTを実行すると、次のeventまでinstruction started 0になる。

これもreal CPU全体へ同じbinary encodingを一般化しない。

「命令札は眠らない」は比喩としても強すぎる。

止まる条件と再開するeventを観測する。

restore handoffまで残り21秒

draft count 2を、restore slot count registerへ渡す。

残り二十一秒。

source draftはread-onlyに保つ。

instruction memoryは承認済みthree-card fixtureだけを使う。

PC 0からsingle-stepする。

decoded operation、operand、result、next PCが予定と違えば、次stepへ進まない。

最後はWAIT_EVENTで止まり、二slot以外を開かない。

イトはdata bridgeの前へ、三枚のroute cardを置いた。

イト

A。dataの10をinstruction slotへ入れ、decoderが選んだoperationをそのままcommitする

イト

B。PCとdecodeを飛ばし、output registerへ2を直接押し込む

イト

C。data railを守り、three-instruction programをPC 0から一stepずつ実行する

Aは、data schemaをtoy opcodeへ誤変換する。

Bは、結果だけを作ってどのinstructionが書いたかを失う。

Cなら、instructionとdataを別railに保ち、state changeを一つずつ確かめられる。

イトがdata-to-opcode bridgeを閉じ、ordered instruction railを開いた

イトは左手で、data-to-opcode bridgeのred gateを閉じた。

direct-output crankにもdark lockを掛ける。

右手で、three-card instruction railのguardを開いた。

PC markerを最初のcardへ置く。

イトがデータを命令口へ渡す赤い橋と出力直結ハンドルを閉じ、保護したデータ札とは別に三枚の命令札を順番どおり開く
dataの10をopcodeへ変えず、PCが指すthree-instruction programを一stepずつ進める。

lower data railには、blue draft_count = 10 cardを残す。

upper instruction railには、fixture専用の三cardだけを置いた。

PC 0  LOAD_COUNT_TO_R0
PC 1  STORE_R0_TO_SLOT_COUNT
PC 2  WAIT_EVENT

これはlab用pseudocodeであり、特定real ISAのmachine instructionではない。

PicoはPC markerとcurrent instruction cardの境界だけを照らす。

card、PC、register、gateへ触れない。

三stepで、二つのslotが開いてCPUは待った

イトはstep leverを一度だけ引いた。

before PC        0
fetched          LOAD_COUNT_TO_R0
operand data     10
decoded count    2
after R0         2
next PC          1

queue clear lampは点かない。

二度目。

before PC        1
fetched          STORE_R0_TO_SLOT_COUNT
operand R0       2
slot count       2
next PC          2

二つのrestore slotが開いた。

三度目。

before PC        2
fetched          WAIT_EVENT
core state       waiting
instruction started after wait  0
next PC          3
test queue cleared     0
source drafts changed  0
restore slots open     2
unexpected PC          0

イトはstep leverから手を離した。

「dataを命令にしなくても、programがdataを読んで結果を書けた」

single-stepしたため、automatic runより時間はかかった。

でもどのinstructionが、どのoperandを読み、何を書いたかをtraceへ残せた。

今回の三stepはtoy fixtureのinstruction数であり、real applicationのkey一回に必要な数やcycle数ではない。

CPU traceを確認する順番

最初にexecution contextを固定する。

対象ISA、mode、program image、start PC。

次にcurrent instructionを確認する。

PCの位置。

fetchされたbits。

decodeされたoperation。

source / destination operand。

実行前後のregister、memory、visible output。

next PC。

raw bitsだけを見て、high-level intentを決めない。

illegal instruction、instruction fetch不可、unexpected branch、operand mismatchが出たら、推測で次stepへ進まない。

simple modelで説明するときも、pipeline overlapやspeculationがないと断定しない。

反対に内部順序が複雑でも、ISAから見えるresult、exception、control flowの境界へ戻って調べる。

一つのlaneへ、千件のwork cardが来た

WAIT_EVENT中の工房へ、新しいbellが鳴った。

CPU laneが再開する。

奥のdistributorから、同じ形のwork cardが千枚届いた。

independent work items   1000
current general lane        1
first round active           1
waiting items              999

イトはthree-card programを千回copyしようとした。

隣のdoorが開く。

片方には、少数の大きなgeneral-purpose lane。

もう片方には、同じ形のworkを並べる細いlaneが何百本も続いていた。

さらに奥では、決まった計算形に合わせたmatrix floorが光る。

同じbitsを実行できても、同じworkloadで同じ速さや効率になるとは限らない。

イトは一枚目を配る前に、work cardの形を見直した。

次回、ピコルート第97話。

イトは、千件を一人の工房長へ並べた|CPU・GPU・NPUは何が違う?

この物語を、解説で深める

第96話で生まれた疑問を、解説記事で少し深く見ていきます。物語で感じた不思議さを残したまま、言葉と仕組みを順番に整理しましょう。

コンピューターはどう命令を処理する?CPUの取出・解読・実行を読む