💻

『コンピュータシステムの理論と実装』を読み終えました

2022/05/20に公開

『コンピュータシステムの理論と実装』を読み終えました。結論、読み終えるのに100時間かかりましたが、読んで本当に良かったので書籍の紹介と感想を記します。

書籍の紹介

ハードウェア(NAND回路)からアプリケーションまで、コンピューターに関する幅広いレイヤーのトピックが記載されています。原著は『The Elements of Computing Systems』で、アメリカの大学のコンピューターサイエンスの授業で扱われていて、内容に定評のある書籍です。

書籍の説明文は以下です。

コンピュータを理解するための最善の方法はゼロからコンピュータを作ることです。コンピュータの構成要素は、ハードウェア、ソフトウェア、コンパイラ、OSに大別できます。本書では、これらコンピュータの構成要素をひとつずつ組み立てます。具体的には、NANDという電子素子からスタートし、論理ゲート、加算器、CPUを設計します。そして、オペレーティングシステム、コンパイラ、バーチャルマシンなどを実装しコンピュータを完成させて、最後にその上でアプリケーション(テトリスなど)を動作させます。実行環境はJava(Mac、Windows、Linuxで動作)。
https://www.oreilly.co.jp/books/9784873117126/

読んだきっかけ

私は文系卒で30歳からエンジニアになった身です。
普段はRubyによるサーバー開発をメインに、JavaScriptを使ったフロントエンドの開発も携わっています。自分が扱うアプリケーションレイヤーについては、日々理解度が上がってきていると感じるものの、より下のレイヤーについては自信がありません。

とはいえ、低レイヤの技術は得られた知識・経験を長くに渡って使えそうであるため、いずれは学びたいと思っていました。また、コンピューターサイエンス専攻の方々から見える景色に憧れがあり、コンピューターを学ぶことで少しでも近づけるのではないかという期待もありました。

課題は学習するための時間の確保でしたが、2022年の5月にGWに連休を取得できる予定があったため、読むことに決めました。

コンピューターサイエンスの前提知識

本書を読むにあたり役立った過去の経験を記します。

  • 基本情報技術者 取得
  • 『Goならわかるシステムプログラミング』を読む
  • 『オブジェクト指向でなぜつくるのか』を読む

ビット演算やCPU、メモリ、オブジェクト指向について基礎的な知識を持っていました。

書籍の良かったところ

本書の良かった点について紹介します。

手を動かしながら学べる

1章ごとに仕様とテストツールが与えられ、仕様を満たすためにプログラムを書き、テストツールで検証する必要があります。
必ず自分でプログラムを書くステップがあり、理解が曖昧なままだとテストを通すことができません。コーディングとデバッグを通して自ずと理解度が上がっていきます。

手を動かしながらすすめるので、楽しく進められます。

GitHubに回答例が載っている

書籍の課題は、回答は一切載っていません。そのため、どうしても進められなくなった場合は、他の方が書いたコードを参考にするのが良いでしょう。GitHubでnand2tetrisと検索すると、多くのリポジトリがヒットするので、いくつかピックアップして見てみると、実装の参考になることが多いです。

難しい章は、参考にしたリポジトリのコードがPythonやJavaScriptで書かれていたので、Rubyに書き換えるような写経をすることで、課題をクリアしていきました。

参考させていただいたリポジトリは下記です。

私のリポジトリはこちら。使い慣れているRubyで実装しました。

書籍のサポートツールが使いやすい

本書にはハードウェアの章がありますが、実際にハードを買う必要はなく、付属するシミュレータを使うことができます。他にも、サポートツール類が充実し、各OS(Mac、Window、Linux)に対応しています。

ハードウェアを買うのは心理的・金銭的ハードルが高く感じられたため、ソフトウェアで完結できるのは嬉しい点です。

読書メモ

各章ごとの読書メモと、所要時間、加えて実装が必要な章は体感の難易度を記載しています。

1章ブール論理

所要時間: 10時間
難易度: ★★

  • And、Or、Notなどの基本ゲートははNandを用いて表現できる
  • どのようなブール関数でも、And、Or、Notを用いて表現できる

2章ブール算術

所要時間: 5時間
難易度: ★

  • コンピューターで行われる算術演算と論理演算は算術論理演算機(ALU)によって行われる
  • 2の補数を用いることで符号付きの整数を表現することができ、正と負の加算を行える

3章順序回路

所要時間: 5時間
難易度: ★★★

  • 組み合わせ回路は入力値の組み合わせによって、関数の値を決定する
  • 値の状態を保持するための記憶素子は、順序回路(フリップフロップ回路)から構築できる
  • DFFは値を保持するために2つの出力を持つ
  • メモリははレジスタから構成される

4章機械語

所要時間: 5時間
難易度: ★★★

  • 機械語はアセンブリとバイナリの2通りで表現できる
  • アセンブリはニーモニックから構成され、アセンブラを利用しバイナリとなる
  • 機械語はプロセッサ(CPU)とレジスタを用いて、メモリを操作するように設計されている
  • メモリには、データを格納するデータメモリと機械語の命令を格納する命令メモリがある

5章コンピュータ・アーキテクチャ

所要時間: 10時間
難易度: ★★★★

  • ノイマン型アーキテクチャはCPUを中心にメモリを操作し、入力を受け取り出力をする
  • メモリマップドIOはIOデバイスのための領域をメモリ上に割り当てる
  • CPUはメモリ、ALU、レジスタ(データレジスタ、アドレスレジスタ、プログラムカウンタ)、制御ユニットから構成される

6章アセンブラ

所要時間: 5時間
難易度: ★★★

  • アセンブラは、アセンブリコマンドを構文解析し、領域ごとに機械語のビットを生成する
  • アセンブリの命令には、計算命令とアドレス命令の2つがある

7章 8章 バーチャルマシン(スタック操作、プログラム制御)

所要時間: 20時間
難易度: ★★★★★

  • バーチャルマシンによって、異なるコンピューターにおいて中間コードを実行することができ、移植性が高い移植性が高められる
  • VM変換器はVMコードをアセンブリへ変換する
  • VM変換器は、計算モデルにスタックマシンを利用し、仮想的なメモリセグメントを操作する
  • 各オブジェクトのデータはオブジェクトのフィールド値を表した数値のリストとして、RAM上にシリアライズされる
  • サブルーチンサブルーチンを開始してらリターンコマンドが実行されるまでの間、メモリ中にローカル変数が保持される

9章高水準言語

所要時間: 2時間

  • Jackの言語仕様について

10章 11章 コンパイラ(構文解析、コード生成)

所要時間: 40時間
難易度: ★★★★★

  • 構文解析のための技術は応用範囲が広い
  • 構文解析器はトークナイザとパーサーから構築される
  • トークンはプログラムをプログラムを意味のある最小単位に分割された文字のこと
  • パーサーはトークンを言語構造へグループ化したもの
  • トークンを1つずつ解析するだけでは判別できないものは、先読みする
  • 構文木を逆ポーランド記法で出力すると、スタックベースのVM言語を出力できる

12章 オペレーティングシステム

所要時間: 1時間

  • OSによって、ハードウェアに特化したサービスがカプセル化され、ソフトウェアから使いやすくなっている
  • OSは、高水準言語を抽象データ型を用いて拡張している

13章 さらに先へ

所要時間: 0.5時間

  • ハードウェアの実現、ハードウェアの改良、高水準言語、最適化、通信など、様々な拡張が可能である

最後に

低レイヤについて理解が深まったと当時に、書籍の理解度はまだ5割くらいなので、今後また読み返したいなと思います。時間の制約上、OSの章の実装ができなかったのが心残りです。OSの実装は今後取り組むか、別の本で学び直すかしたいなと思っています。

今回は、アセンブラ、バーチャルマシン、コンパイラの実装にRubyを使いましたが、別の言語で実装するのも楽しそうですね。

Discussion