WWI 初の現代的コンピュータ
目次
当時のメモリの問題点
これが如何に無謀なプロジェクトであったか、当時の技術水準を知らなくてはなりません。
まず、当時コンピューターの速度を決めていたのは「メモリ」でした。
当時使われていたメモリは大きく分けて2種類。
安価で大容量だが、シーケンシャルアクセスで非常に速度の遅い水銀遅延管と、高価で容量は少ないが、ランダムアクセス可能で速度の速いウィリアムズ管でした、
ところで、ウィリアムズ管は静電気で記憶を保持します。しかし、静電気ですから、やがて放電して消えます。
そこで、データを必要としていなくても放電する前に読み出しを行い、再度書き込む、という操作が必要です。これを「リフレッシュ」と呼びます。
リフレッシュは、メモリを読んで書く、という作業の繰り返しです。
専用の回路を作り、コンピューターの演算動作とは無関係に動作させます。
しかし、メモリから見ればリフレッシュ回路の要求だろうがコンピューターからの要求だろうが、「データの読み書き」であることに違いはありません。
リフレッシュ中にコンピューターがデータを読み出そうとしても読み出せず、待たされることになります。
当然ですが、大容量メモリになるほど、多くのビットをリフレッシュする必要が出てきます。
結果的に、大容量メモリはコンピューターを待たせる可能性が高くなります。
WWI では、大容量のメモリを搭載することが前提でした。ウィリアムズ管の「大容量になると遅くなる」という特性は、何としても解決しないといけないものでした。
そこで、WWI 開発プロジェクトでは、「改良ウィリアムズ管」の開発が行われることになりました。
これはウィリアムズ管の高速性を活かしたまま、リフレッシュが不要になるという夢のメモリでした。
演算回路
メモリ開発と同時に、高速な演算回路が設計されます。
当時は、水銀遅延管が一般的なメモリだったため、1bit づつ読み出しては処理する、という方法が普通でした。
この方法の利点は、UNIVAC I のように 72bit もの処理を行うコンピューターを作ったとしても、回路構成は 1bit 分でよい、ということです。
しかし、WWI は、高速なランダムアクセスメモリが「開発できる」ことを前提に設計されます。
水銀遅延管と異なり、まとめて数ビットの読み出しが可能なはずでした。
それを 1bit づつ処理するなんて無駄なことです。
そして、WWI は 16bit を「並列に」処理する設計となります。
当時の他のコンピューターに比べると少ないビット数ですが、これでも回路構成は十分複雑になります。
UNIVAC I では 72bit 、IBM 701でも 36bit で演算ができるのに、WWI は 16bit しか扱えないのです。こんなちっぽけなコンピューターでは何もできないだろう…というわけ。
演算できる word長が性能の限界で、速度よりも重要である。これは当時の一般的な考え方です。
WWI がいかに「変わった設計」だったかがわかります。
1bit で済んでいたものを、16 bit まとめて扱おうとすると、信号線が膨大な量になります。
これはまた、別の問題を生じる可能性もありました。
当時のメモリや演算素子は、不安定なものが多く、今よりも信頼性に劣りました。これらの素子を使って、16bit のデータを同時に、高速に転送するとなると…何が起きるか、予測もつきません!
そこで、転送を常に「本来の転送先」と「チェック機構」の2重に行い、WWI 自身が動作をチェックし続けられる仕組みが盛り込まれることになりました。
ただでさえ回路が膨大なのに、その膨大な回路が問題を及ぼす可能性を考慮して、さらに複雑な機構を用意する…
常識的に考えて、問題が大きくなりすぎていました。
これだけの問題が山積みになっていながら、演算部分の設計段階ではメモリが完成しておらず、実際に必要となる調整パラメータがわからないのです。
膨大な信号線を引き回す設計を行いながら、あとでタイミング変更などで膨大な変更点が生じる可能性がありました。
コントロール・マトリックス
ここで、巧妙な仕組みが考案されます。
これまで、コンピューターというのは非常に複雑な回路であり、すべてを一体化して設計しないとうまく動かない…と思われていました。
しかし、WWI は思い切って機能ブロックごとに分割して設計するようにしたのです。
機能ブロックに必要なのは、word 単位の入出力だけ。信号の形式さえ守れば、他の部分を気にせずに設計できます。
機能ブロックは、「組み合わせやすい最小単位」で設計されます。
コンピューターの機能は、当然ながら電子回路で作られています。加算機能を使うには加算回路を、乗算機能を使うには乗算回路を動かすのは、当然のことでした。
しかし、WWI では、命令と演算回路が一致しません。
命令の詳細は別ページに譲りますが、複数の命令で同じ回路を共有したり、1つの命令を複数の回路を順次動作させることで実現したりしています。
なんでそんなややこしい仕組みを…と思うかもしれませんが、こうするほうが「機能単位」では回路が簡単になり、高速化できるのです。また、重複する回路を作らなくて済むため、全体のサイズを小さくすることもできます。
これらの「最小単位」の機能ブロックは、すべてが 16bit の信号線を「共用」します。
こうすれば、信号線を多数引き回して悲惨な状態になるのを避けることができます。
共用する場合の問題は、回路が同時にデータを送ろうとしたときに、データが衝突して混乱してしまうかもしれないことです。
周辺回路が動作するタイミングを調停し、バスを順序良く使用させる仕組みが必要です。
複数の機能ブロックを順序良く動作させ、データが衝突しないように制御する…。この制御を行っているのが、タイミング・コントロール・マトリクス回路でした。
この回路は「マトリクス」(2次元配列)になっていて、クロックごとに適切な回路に信号を送ります。
示したのは、命令を読み込み、解釈する部分まで。図の上にタイミングを示す数字が描かれ、「8クロック」を基準に設計されていることがわかる。
注目すべきは、このタイミングチャートの一部は、「次の命令」の実行と重なるように設計されていることです。
命令の「読み込み」「解釈」の回路は、命令の「実行」の回路と独立しています。つまり、読み込み・解釈と、実行は同時に動作することができるのです。
これは、現代の用語を使えば、2段のパイプラインをすでに備えていたことになります。
マトリクスの仕組みであれば、メモリユニットの仕様が変わり、動作速度が変わったとしても、マトリクスの調整だけで問題を解決できます。
さらに、新しい演算回路を追加したいときも、全体を調整するのではなく、マトリクスにちょっと手を加えるだけで済みます。
この柔軟性は「プログラム」に他なりませんでした。
Whirlwind は「ハードウェアでは作れない複雑な計算を、プログラムで行う」ために設計されましたが、そのコンピューター自体が複雑になりすぎるのを避けるため、さらに小さな回路でプログラムを行っていたのです。
この仕組みはこの後のコンピューターでも使われるようになり、現在では「マイクロプログラミング」とか、「マイクロコード」と呼ばれています。