「コンピュータシステムの理論と実装」をRustで。

良い本がある

コンピュータシステムの理論と実装という良い本がある。

コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方

コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方

nand と flip-flap だけが最初に与えられた素子として、それをもとに加算器やメモリを組み立ててコンピューターを組み立てる。 そして、そのコンピューター上で動くテトリスというコンピュータゲームを開発するというものだ。(実は最後はテトリスではないが)

本書の前書き曰く、ハードウェア、アーキテクチャオペレーティングシステムプログラミング言語コンパイラ、データ構造とアルゴリズム、ソフトウェアエンジニアリングという、コンピュータサイエンスの基礎をザックリ学べてしまうようなものだ。

プログラマ人生が終わる前に

プログラマという職で日々過ごしていると、同じ職種の人と学生時代にどのようなカリキュラムでコンピュータサイエンスを学んできたかという話になることがある。

こういう時、良い学校を出ている人などは「CPU作りました」とか「コンパイラ書きましたね」というような話がサラッと出てきてさすがに良い学校出ていると深いところまでやるのだなと感心する。少し前には、東大のCPU実験はすごいぞという話もありましたね。

そして自分はこのあたりの事を真面目に修めてないなという劣等感のようなものが頭をもたげてくる。

低レイヤの基礎というのは、実際のところ実務で使うシーンがある人はごく一部の人たちだけだ。我々は巨人の方の上に乗って生きている。自分は幸いにも(不幸にも)このレイヤに携わる必要はないのだけど、そういうのを全く知らないままプログラマとしての人生をいつか終えてしまうのだろうかと考えると、それはそれで損をしている気がしてくる。

プログラマ人生が終わる前にやっておきたい。

というわけでやっている

この本自体は通読するだけなら簡単。なるほど、こういう風にできているんだねと理解したふりが簡単にできてしまう。

けど実習をやらないとさっぱり身につかないので実習をやらないと意味がない。

しかし、そのまんま実装したって与えられた環境の上で実装することになってそんなに楽しくないので新しい言語の勉強がてら Rust で実装を始めることにした。

具体的には、以下のルールで始めた。

  • CPUを作るにあたって Rust の機能で使っていいのはlet、自作関数、struct、traitだけ。
    • if とか for とか配列操作に便利な関数とか使わない。
  • CPUは nand と flip-flap のみを積み上げて実装する。
    • メモリだけはさすがに速度的に厳しいのでネイティブ実装を使ってもいい。
  • テストやログ出力するときは Rust の機能を使ってもいい。
  • Screen と Keyboard といった入出力の実装は Rust のライブラリを使ってもいい。

実際のプリミティブは以下の2つで始めた。

// nand 関数
pub fn nand(a: bool, b: bool) -> bool {
    !(a && b)
}
// data flip-flop
pub struct Dff {
    pub pre_value: bool,
}

impl Dff {
    pub fn new(initial_state: bool) -> Dff {
        Dff {
            pre_value: initial_state,
        }
    }

    pub fn dff(&mut self, a: bool) -> bool {
        let result = self.pre_value;
        self.pre_value = a;
        result
    }
}

途中何度か中断が入ったが兎にも角にもnandとflip-flapだけでコンピュータの実装が終わった。

書籍でいうと5章までが終わったというところだ。

リポジトリはこんな感じ。 github.com

感想

実装してみてわかったのは「何もわからん」という事だ。

もちろん「なるほど、こういう風に動くのだな」とか「これを組み合わせてこういう動きを作っているのだな」という細部の動きは実装時にはわかる。

だけど「なぜこのCPUの仕様を考えつくことができたのか」みたいな大きなデザインについては自分が一から組み上げる想像は全くできなかった。

感じたのは「ノイマンという人はまさに天才なのだな」だったり「CPU設計者のジム・ケラーみたいな人が同時代に何人も出てくるはずがない訳だ」という事ばかりだった。

つまり「自分にはたどりつけない巨人の影が以前よりはっきり見えた」という事だ。

あと nand と flip-flap のみで実装する縛りだと全然 rust の勉強にならないという事に途中で気づいたのも辛かった。

先は長い

ともあれ、5章まででいわゆるハードウェアの世界は終わり。6章からはソフトウェアの世界になるので今までよりは想像できる領域を勉強できそうなので、プログラマ人生が終わる前に最後までやろうと思っている。

この本は積読や通読はしたけど実装はせずに終わってしまったりする人が多いタイプの本だと思うので、今後梅田方面でモクモク会などができればいいなと思っております。

その節はどうぞよろしくお願いいたします。