01 / 読書ガイド
読書ガイド
引用
Bryant, R. E., & O'Hallaron, D. R. (2015). Computer Systems: A Programmer's Perspective (3rd ed.). Pearson.
章の要約
本書は3部12章と、エラー処理に関する短い付録からなります。著者は取捨選択の基準を明確に述べています。ユーザレベルの C プログラムの性能、正しさ、有用性に影響する話題だけを取り上げる、というものです。各章の末尾には要約と参考文献の注があり、多くの章には演習問題も付き、本文中の練習問題の解答は各章の末尾にまとめられています。
第I部:プログラムの構造と実行(第1〜6章)
第1章:A Tour of Computer Systems(コンピュータシステムの旅)
この章は、単純な「hello, world」プログラムの一生をたどりながら、主な主題を紹介します。情報とはビットに文脈を加えたもの、コンパイルシステムによるプログラムの変換、それを動かすハードウェアの構成、キャッシュと記憶装置の階層、オペレーティングシステムのプロセス・スレッド・仮想メモリ・ファイル、そしてネットワークを通じた通信です。章末では、繰り返し現れる3つの主題として、アムダールの法則、並行性と並列性、抽象化を挙げます。
第2章:Representing and Manipulating Information(情報の表現と操作)
この章は、情報の格納(16進表記、ワードサイズ、バイト順序、C のビット単位演算と論理演算)、整数の表現(符号なしと2の補数の符号化、変換、符号拡張と切り捨て)、整数演算、浮動小数点数(IEEE 表現、丸め、C の浮動小数点数)を扱います。著者は、2つの正の数の和が負になりうることなど、プログラマにとっての帰結を強調しています。また、読者がこの章を最も重く感じやすいことを認めており、第3版では記述が数学的になる箇所を示して、先に流し読みできるようにしています。
第3章:Machine-Level Representation of Programs(プログラムの機械語レベルの表現)
ここで読者は、C コンパイラが生成する x86-64 のコードを読むことを学びます。データ移動と算術演算、条件コード、ジャンプ、ループと switch 文、プロシージャと実行時スタック、配列、構造体と共用体、アラインメント、ポインタ、gdb デバッガの使用、バッファオーバーフローとその防御、浮動小数点のコードです。
第4章:Processor Architecture(プロセッサアーキテクチャ)
この章は、Y86-64 命令セットを軸に簡略化したプロセッサを設計します。論理設計とハードウェア制御言語 HCL を紹介し、逐次実装を段階的に作り、パイプライン処理の原理と限界を説明し、ハザード、例外処理、制御論理、性能解析を含む5段のパイプライン実装へと発展させます。
第5章:Optimizing Program Performance(プログラム性能の最適化)
この章は、最適化コンパイラにできること・できないことから始め、ループの無駄、冗長なプロシージャ呼び出し、不要なメモリ参照を取り除きます。現代のアウトオブオーダープロセッサの動作モデルを示したあと、ループアンローリング、複数のアキュムレータ、再結合、レジスタのスピルや分岐予測ミスといった制約要因、メモリ性能、プロファイリングを扱います。
第6章:The Memory Hierarchy(メモリ階層)
この章は、記憶技術(RAM、ディスク、ソリッドステートディスク)、局所性、メモリ階層、キャッシュメモリ(ダイレクトマップ、セットアソシアティブ、フルアソシアティブ、書き込み、キャッシュパラメータが性能に与える影響)を扱います。最後に、キャッシュに優しいコードの書き方と、性能を「メモリ山脈」として見る見方を示します。
第II部:システム上でのプログラムの実行(第7〜9章)
第7章:Linking(リンキング)
第7章は、コンパイラドライバ、静的リンク、オブジェクトファイル、シンボルとシンボル解決、再配置、実行可能ファイルとロード、共有ライブラリによる動的リンク、位置独立コード、ライブラリインターポジショニング、オブジェクトファイルを操作するツールを扱います。
第8章:Exceptional Control Flow(例外的な制御フロー)
この章は、例外、プロセス、プロセス制御、シグナル、非局所ジャンプを紹介します。著者は、この章を終えると、ジョブ制御付きの簡単な Unix シェルが書けるようになると述べています。
第9章:Virtual Memory(仮想メモリ)
この章は、物理アドレッシングと仮想アドレッシング、キャッシュの道具としての仮想メモリ、メモリ管理と保護、アドレス変換、Intel Core i7 と Linux のメモリシステムの事例研究、メモリマッピング、動的メモリ割り当て、ガベージコレクション、C プログラムによくあるメモリ関連のバグを説明します。
第III部:プログラム間の相互作用と通信(第10〜12章)
第10章:System-Level I/O(システムレベル I/O)
この章は、Unix I/O、ファイル、オープン、読み書き、ショートカウントを扱う堅牢な I/O パッケージ、ファイルのメタデータ、ディレクトリ、ファイル共有、I/O リダイレクション、標準 I/O を扱い、次の2章の準備をします。
第11章:Network Programming(ネットワークプログラミング)
この章は、クライアントサーバモデル、ネットワークとグローバルな IP インターネット、ソケットインタフェース、Web サーバ、そして Tiny Web サーバを紹介します。著者はこれを、簡単な Web サーバにたどり着くための、ネットワークプログラミングの薄い断面と呼んでいます。
第12章:Concurrent Programming(並行プログラミング)
最終章は、プロセスによる並行性、I/O 多重化による並行性、スレッドによる並行性を比較し、続いて共有変数、セマフォによる同期、並列化のためのスレッドの利用、そしてスレッドセーフ性、リエントラント性、競合、デッドロックといった他の問題を扱います。
付録A:Error Handling(エラー処理)
Unix システムでのエラー処理と、エラー処理用のラッパー関数に関する短い付録です。
主要概念
第I部:プログラムの構造と実行(第1〜6章)
- 2の補数と IEEE 浮動小数点の表現:有限のビットパターンがなぜ意外な算術結果を生むのか。
- 機械語レベルのコードと実行時スタック:C の構文やプロシージャが命令にどう対応するか。
- パイプライン処理:命令の各段階を重ねて実行することと、それを制限するハザード。
- 局所性とメモリ階層:性能を決めるのがプロセッサの速度だけでなくアクセスパターンである理由。
第II部:システム上でのプログラムの実行(第7〜9章)
- リンキングと再配置:オブジェクトファイルとライブラリが実行可能ファイルになる過程。
- 例外的な制御フロー:並行性の源としての例外、シグナル、プロセス。
- 仮想メモリと動的割り当て:アドレス変換と、malloc・free の実装。
第III部:プログラム間の相互作用と通信(第10〜12章)
- Unix I/O とソケット:ネットワークプログラムの構成要素。
- 並行サーバ:プロセス、I/O 多重化、スレッドの比較。
- 同期:セマフォ、競合、デッドロック。
批判的分析
長所
- 明快な組織原理。 著者は「作る側の視点」とプログラマの視点を対比し、すべての話題に同じ基準を適用しています。そのため、リンキング、シグナル、malloc は含まれ、加算器やバスの詳細な設計は省かれています。
- 能動的な学習が組み込まれている。 新しい概念のあとに練習問題が続き、解答は各章の末尾にあります。演習問題には数分から10時間かかる実習までの難易度表示が付いています。コード例はすべて Linux でコンパイルして実行されており、ソースは本書のサイトから入手できます。
- 長年続く授業に由来するラボ。 序文には、本書に付属するラボとして、データ、バイナリ爆弾、バッファオーバーフロー、アーキテクチャ、性能またはキャッシュ、シェル、malloc、プロキシのラボが紹介されています。独習者向けの解答なし版は著者のサイトにあります。
- C 初心者への配慮。 「New to C?」の注が言語上の要点を示し、Web アサイドが補足的な内容を本文から外に出しています。
- 柔軟な使い方。 序文は各章を5種類の授業タイプ(計算機構成の授業からシステムプログラミングの授業まで)に対応づけています。
短所
- 単一のプラットフォームに結びついている。 本書は x86-64 の機械語、gcc コンパイラ、Linux を対象としています。他の命令セットを使う読者には異なる機械語が見えますが、全体的な挙動は同じはずだと著者は述べています。
- C の知識が必要。 著者は C か C++ に慣れていることを前提としています。Java しか知らない読者は余分な努力が必要で、Python、Ruby、Perl しか知らない読者は先に C を学ぶよう勧められています。
- 簡略化されたプロセッサ。 第4章はパイプラインを教えるために Y86-64 プロセッサ(x86-64 を縮小したサブセット)を設計しており、これは教育用の設計であって、市販のプロセッサのモデルではありません。
- 意図的な取捨選択。 著者はネットワークプログラミングの章を薄い断面と述べており、取捨選択の基準により加算器設計のようなハードウェアの話題も外されています。
- ハードウェアの例が古い。 この版は2015年のもので、プロセッサやキャッシュの例は当時のマシンを反映しています。
コースにおける位置づけ
Computer Systems: A Programmer's Perspective は、ソフトウェア側から機械を見る本です。Petzold の Code は一般読者向けの物語的な入門書、Nisan と Schocken の The Elements of Computing Systems は論理ゲートから始めてプロジェクトでコンピュータを組み上げる本で、どちらも本書の前に読めます。Harris と Harris の Digital Design and Computer Architecture, RISC-V Edition はハードウェアから上へ進み、学生にプロセッサを設計させるため、本書の第4章と組み合わせられます。大学院レベルのアーキテクチャの定量的研究は後に来ます。Hennessy と Patterson の Computer Architecture: A Quantitative Approach、そして、第5章がモデルで概略を示すにとどまるアウトオブオーダーのスーパースカラプロセッサを詳しく扱う Shen と Lipasti の Modern Processor Design です。
本書の使い方
本書は、C か C++ でプログラムを書け、自分のプログラムの下で何が起きているかを知りたい情報工学・工学系の学生に向いています。ハードウェアやアセンブリ言語の経験は前提とされていません。
序文の授業タイプに沿った実践的な進め方は次のとおりです。
- プログラマ向けの授業の中核: 第1〜3章と第5〜9章。データ表現から機械語、最適化、メモリ階層、リンキング、プロセス、仮想メモリまでをたどります。
- システムプログラミングの授業なら追加: 第10〜12章。並行 Web サーバの構築へとつながります。
- 計算機構成の授業なら追加: 第4章のプロセッサアーキテクチャ。
- 実習: 各概念が出てきたら練習問題を解き、特にデータ、バイナリ爆弾、バッファオーバーフロー、キャッシュ、シェル、malloc の各ラボに、Linux マシンか仮想マシンを手元に置いて取り組んでください。
