小さなCPU:Little Man Computer

プログラムと計算に使う数値は、同じ百個のメールボックスに入っています。少しずつ実行すると、フェッチ・解読・実行の各動作に合わせて表示が変わります。読み出したメールボックスは青、書き込んだものは琥珀色。次に実行する命令は紫の枠で示されます。

インタラクティブシミュレーションを読み込んでいます...

レッスン

理論 — 小さなCPU:Little Man Computer

フェッチ・解読・実行サイクルは、プロセッサが命令ごとに行う一連の処理です。フェッチでは、PCの値をMARにコピーし、そのメールボックスの内容をMDRに読み出してCIRにコピーします。PCには1を加えます。解読では、命令を操作(百の位)とアドレス(下二桁)に分けます。ただし、901、902、000はそれぞれ全体でINP、OUT、HLTを表すコードで、メールボックスを指定しません。実行では、解読した命令の処理を行います。命令によっては、MARとMDRを通じてさらにメールボックスを読み書きします。

各記号の意味

PC
プログラムカウンタ:次にフェッチする命令のアドレス
MAR
メモリアドレスレジスタ:これから読み書きするメールボックスのアドレス
MDR
メモリデータレジスタ:読み出した値、またはこれから書き込む値
CIR
現在命令レジスタ:実行中の命令
ACC
アキュムレータ:ADD、SUB、LDAの結果を格納するレジスタ
前提
スチュアート・マドニックが考案したLittle Man Computer(MIT、1965年)では、SUBの結果が0未満になった場合や、ADDの結果が999を超えた場合の動作は定められていません。このシミュレーターのアキュムレータは−999から999までの値を保持し、BRPは符号を調べます。結果がこの範囲を外れると、値を折り返さず、オーバーフローとして実行を停止します。教育用シミュレーターでは、この点の扱いが異なります。アキュムレータの値が常に0から999の範囲に収まるプログラムなら、どれでも同じように動作します。

コンピュータには数値と命令の区別がつかない 🖖

データを命令として実行を押してみましょう。LDA nとOUTで105を一度だけ出力するつもりのプログラムですが、HLTを書き忘れています。そのため、PCは105を格納したメールボックス02へ進み、ほかの命令と同じように105をフェッチします。命令として読むと、105はADD 05。メールボックス05の値は20です。次のDATの値は902で、これはOUTなので125が出力されます。その次の0はHLT。ここで停止します。メールボックスの中には、内容が命令なのか数値なのかを示す印はありません。PCが指せば命令、LDAやADD、SUBが参照すればデータです。この105も、最初の命令では数値として読み出され、三番目の命令として実行されました。これがプログラム内蔵方式の考え方です。初めて実際に動作したのは、1948年6月のManchester Babyでした。

リストの次の値を読むために、自分自身を書き換える 🖖

リストの合計を押し、メールボックス00を見てください。最初の値は517、つまりLDA 17で、リストの先頭の数値を読み込みます。LMCの命令にはアドレスが埋め込まれています。命令がアドレスを取り出せるレジスタもないため、「今読んだメールボックスの次」を指定できません。LDA 17、ADD 18、ADD 19と並べて書けば、このリストは足せますが、それより長いリストには対応できません。そこで、要素数に応じて同じループを繰り返せるよう、プログラムは自分の先頭の命令を数値として読み込み、1を足して元の場所に書き戻します。517が518になり、命令はLDA 18に変わります。ループを5回繰り返し、メールボックス00も5回書き換えます。最後にできるLDA 22は、実行前に残りの個数が0になるため使われません。実際のプロセッサには、こうした処理のためにレジスタからアドレスを取得する仕組みがあります。プログラムを書き換えずに、リストを順にたどれるのです。

読み出しの大半は、自分のプログラムを読むためのもの 🖖

どの命令も、処理を始める前にメールボックスを1回読み出します。これがフェッチです。LDA、ADD、SUBはさらに1回読み出し、STAは1回書き込みます。分岐命令とINP、OUTでは、フェッチ以外にメールボックスへのアクセスはありません。足し算で掛け算で6 × 7を計算すると、フェッチは65回、オペランドの読み出しは30回、書き込みは16回。プロセッサとメモリの間のアクセス全体の58.6%が、命令を取り出すためのものです。積が999以下になるすべての入力の組み合わせで、この割合は57.2%から69.2%の範囲に収まります。プログラムもデータも、同じ経路を通って同じメモリとやり取りされ、一度に転送できるのは一つだけです。ジョン・バッカスは1977年のチューリング賞受賞講演で、この経路を「フォン・ノイマン・ボトルネック」と呼びました。

全プロセスの詳細解説

  1. 2 × 99には801回、99 × 2には25回の命令実行が必要なのはなぜか 4 ステップ

    2 × 99、時間のかかる順を押してから、入力を99、2に変えてください。どちらも198が表示されます。それぞれの実行で命令が何回実行されるか数え、その回数を表す式を求めましょう。積がメールボックスに収まる範囲で、最も時間のかかる入力順では命令数が最大でいくつになるか求めてください。

    この問題をツールで開く

    1. ループに入る前に、INPを2回、STAを2回実行します。計4回です。ループ本体はLDA b、BRZ、SUB one、STA b、LDA total、ADD a、STA total、BRA loopの8命令。これをbの初期値と同じ回数だけ繰り返します。

    2. bが0になると、ループ内ではLDA bとBRZだけを実行し、続いてLDA total、OUT、HLTで終了します。最後に加わるのは5回。したがって、実行回数は4 + 8b + 5 = 8b + 9で、aの値には依存しません。

    3. b = 99なら8 × 99 + 9 = 801回、b = 2なら25回です。結果の表にも、最初の入力順では801、次の入力順では25と表示されます。

    4. メールボックスに格納できる積の最大値は999。1、999と入力すると、ループは999回繰り返され、命令の実行回数は8,001回になります。999、1ならループは1回だけで、命令の実行回数は17回です。

    解答

    命令の実行回数は8b + 9回。bは二番目の入力値です。 同じ999を求めるにも、入力順によって8,001回と17回、約470倍の差が生まれます。先に入力値を比較し、小さいほうの数だけループを繰り返すプログラムなら、必要な回数は8 × 31 + 9に比較のための命令数を加えた分を超えません。積が999以下のとき、小さいほうの因数は最大でも31だからです。

学習の道すじ

コンピュータはどうやってプログラムを動かすのか

参考文献 (4)