2008-04-13

"コンピュータアーキテクチャのエッセンス" Douglas E. Comer 著

コンピュータアーキテクチャーは、ハードに生きる人間には興味のある分野である。ハードに生きる人間はハードボイルドに反応する。タイトルからして、エレガントでもう少し電子工学を掘り下げてくれるものを期待したが、対象者に学生をも含めた基本書である。ただ、それはそれで意義深い。脳の記憶領域を管理できないアル中ハイマーは、しばしば基本に立ち返らなければならない。この分野の教科書といえば、パターソン&ヘネシーが思い浮かぶ。うちの本棚にも第2版が並んでいるが、隅々まで読み渡したことがない。この機会に基本に立ち返るのも悪くはない。今日、高水準言語を使うことが多くなり、基底のハードウェアを認識する必要もなくなってきた。ただ、プログラム性能と正面から向かい合う組込み系などでは、こうした知識を疎かにはできない。

本書は、工学的な詳細よりは概念に焦点を合わせおり、プロセッサ、メモリ、I/Oといったディジタルシステムの基本要素を網羅しようとしている。また、ハードにがちがちに固まった内容ばかりではなく、OSとプログラマの視点からも解説が施される。ただ、事前知識としてTTLを使った論理回路の説明が少々くどい。学生をも対象としている教科書なので仕方がないのかもしれない。それにしても74シリーズは懐かしい。また、マイクロプログラミングも登場するなど、なかなかの古典振りで、アル中ハイマー世代にマッチした懐かしい香りがする。ちなみに、その世代は16進数で20代である。尚、年齢表記にアルファベットを要する。
著者が本書を執筆した理由の一つに、学生向け授業の内容を嘆いていることが語られる。それは、実践的ではないブール代数に集中した授業や、特定マシンのアセンブラ言語の詳細を学ぶ授業になっているという。この意見は、おいらの学生時代と変わっていない印象で少々意外に感じる。大学の講義とは、時代の流れについていけない官僚的なものなのだろうか?いずれにせよ、おいらがコンピュータ工学を学んだのは卒業後である。学生時代に学んだ知識は役に立っていない、というより睡眠学を研究していた。講義中、夢を操ろうとして金縛りにあったりして友人に笑われたものだ。ただ、それは自我を制御する実験をしていたのである。

コンピュータの性能を語る上で、メモリ制御が中心になるのは仕方がない。フォン・ノイマンアーキテクチャであるストアドプログラム方式は、プログラムとデータの両方をメモリに格納することから、メモリアクセスがボトルネックとなる。特にオペランドによるアドレス指定が弱点となる。間接アドレッシングは性能面からなるべく避けたい。全ての命令セットが同一サイクルで動作するならば、並列パイプラインの構想は優れている。更なる性能改善を求めると、プログラムの流れも考慮する必要がある。実行時間の多くが分岐命令に費やされることから、分岐方向のスケジューリングや、両方の条件を並列評価して不要な値を破棄するなどの手法も現れる。物理的な構成では、複数のメモリをインターリーブなどの手法でアクセス時間を先回りする方策もとられる。また、キャッシュの方法論にも、いろいろと論争が見られる。本書は、こうしたコンピュータの性能改善のための概念を議論している。

1. マイクロコード
CPU内部の複雑さを解消するために、マクロアーキテクチャとマイクロアーキテクチャの二つの抽象化がなされる。マクロ命令をマイクロコントローラが解読して、マイクロコードに分解しステップ実行する。マイクロコードの利点は、コードの抽象化と、回路で構築するより実現が簡単である。欠点は、ハードウェアよりオーバーヘッドが大きい。最近では、CPUにマイクロコードを上書きできる機能を持つものがある。CPUがマイクロ命令セットへのアクセスを提供する理由は、柔軟性と性能である。必要な命令セットの判断は用途によってユーザ側に任せられる。従来のマイクロコード方式は垂直型で、CPUの命令セットをそのまま引き継いだもので、性能面ではあまり魅力がない。これを克服するために水平型が考案された。その構成は、複数の機能ユニットが結合されるデータパスに、マイクロコントローラも結合される。そして、複数の機能ユニットの動作をスケジュールすることを許す。コントローラが命令の先読みで、命令をスケジューリングする機構もある。アウトオブオーダー実行で、命令の状態を追跡するスコアボード機構を利用して、命令順に実行しなくても、順序を入れ替えることにより結果的に同じにする。マクロ命令セットの書き換えは、性能向上のための最適化手法の一つである。

2. 仮想メモリ
メモリコントローラが物理メモリ側に存在するのに対して、MMUはプロセッサ側に配置される。MMUは、物理メモリを多重化し仮想空間を作る。長所は、異なるメモリデバイスを吸収したり、メモリ毎の命令セットやオペランドを用意する必要がない。また、一定のメモリ空間を見せることにより多重プログラミングを助ける。仮想メモリ機構は、プログラムとデータ保護を直結する。その古典的な手法に、ベースと範囲を指定するレジスタを使う方法がある。OSが動的にマッピングし、空間の確保と保護を提供する。メモリ資源が乏しい時代、プログラムを可変サイズのブロックに分割し、必要とするブロックをメモリにロードするセグメンテーションがある。多くの研究と実験からセグメンテーションは衰退化する。問題は、OSがメモリから断片の出し入れを繰り返していくと、小さな未使用領域が細分され、フラグメンテーションが起きる。
次に登場した機構がデマンドページである。これは、セグメンテーションを一般化した方式で、その違いはプログラムの分割方法にある。プログラムの可変サイズに対して、ページによる固定サイズを提供し隙間を無くす。実現するための必要な機構は、失ったページを検出するハードウェアと、外部記憶と物理メモリの間でページを移動するソフトウェアである。ページの置き換えのための、アドレス変換、ページ表の記憶の実装は、そのままボトルネックとなりやすい。その対処で、表引きのためのバッファに連想メモリ(CAM)を使うなどの工夫がある。本書は、TLB(Translation Lookaside Buffer)を使わない仮想メモリは、受け入れ難いほど性能が出せないだろうと語る。TLBという高速検索機構により、ページ表の表引きが効率的に行われる。

3. キャッシュ
キャッシュ技術は、フォン・ノイマンボトルネックを軽減する最適化技術である。キャッシュ置き換えポリシーは、キャッシュがいっぱいになった時、新たな要求を無視するのか、どの古いデータを追い出すかを指定することである。ヒット率を確保するために、当然、頻繁にアクセスするデータを残す。LRU(Least Recently Used)は、最も長い期間参照されなかったデータを置き換えるように指定する。これは、実現が容易で多く利用されているポリシーである。多重レベルキャッシュ構造は、キャッシュの性能向上のためにキャッシュを使う。L1,L2,L3がそれである。L1がチップ内に配置されるのに対して、L2,L3はチップ外に配置される。先読みキャッシュも性能改善に役立つ。初期の機構では、ライトスルーによりキャッシュはコピーを保持していた。別の方法では、キャッシュがローカルとなり、必要に応じてメモリを更新するライトバックがある。書き換えタイミングは、キャッシュの置き換えが生じた時にデータを書き戻す。どのデータを書き戻すかはダーティビットで管理する。
キャッシュ内のランダムな参照を連続アクセスすると性能は悪化する。逆にランダムな参照数を減らすことによりキャッシュ性能は改善される。
キャッシュ機構は、マルチプロセッサ環境では、キャッシュの一貫性を保つのが難しいなど、数々の問題が生じるため、研究者の中でも議論が分かれるようだ。
命令とデータで別々のキャッシュを配置すれば改善されるいう意見がある。また、キャッシュ容量が、参照方法よりも重要であるとした意見もある。つまり、キャッシュ容量が充分確保できれば、命令とデータを混在したところで問題はないという主張である。
他にも、キャッシュの物理的な配置についても議論がある。キャッシュは、プロセッサとMMUの間に配置するべきか?それともMMUとメモリの間に配置すべきか?つまり、キャシュアドレスを仮想空間で使うか物理空間で使うかといった議論である。
プログラマの立場からすると、書かれるコードにはループが含まれる傾向がある。これは繰り返し小さな命令集合を実行することを意味する。プログラマは、何度も同じデータを参照する傾向もある。また、キャッシュを有効に使うために意識したコンパイラもある。キャッシュの仕組みを知っていれば、活用するためにうまくコードを書くプログラマもいるだろう。

4. I/O
一般的にプロセッサの速度と入出力装置の速度に大きな差が生じる。これらを同期するためにポーリングするのは、CPU資源が勿体ない。これを意識しない割込み機構は、おいらの時代には画期的であった。おいらはZ80時代を謳歌した。ワンチップマイコンという言葉が流行り出し、割込み機構とDMAが内臓されているのには感動したものだ。本書は、DMAに加えて、更なる性能改善に、次々にくるデータバッファの数珠繋ぎ、複数の操作を連続させるために操作の数珠繋ぎと続く。また、プログラマの立場から見たデバイスドライバの概念を説明している。低レベルと高レベルのインターフェース、データの共有、待ち行列、デバイス依存部を隠蔽などなど。こうした資源は、ライブラリとしての提供されることもある。また、OSが提供するシステムコールのスタイル、open/read/write/closeパラダイムがある。入出力装置の性能を最適化するために、バッファリング手法が用いられる。バッファリングは、システムコールのオーバーヘッドを減らす。そして、アプリケーション側でタイミングを制御できるflush操作が実装される。

5. マルチプロセッサ
一般的な並列パイプライン処理は、フェッチ/ストアの階層で、その効果は大きい。しかし、マルチプロセッサで物量にものを言わせても、性能向上には限界がある。OSのオーバーヘッドや、アプリケーションによってまったく意味を持たない場合もある。プログラマの視点からすると、ロックと解除を、暗黙的に任せるよりも明示的に並列を意識する方がピンポイントで性能改善されることもある。単に、同種のプロセッサを複数搭載する方法もあるが、科学演算用やグラフィックスエンジンなど異種のプロセッサを組み合わせる場合もある。理論的には、マルチプロセッサの方がその数だけ性能が上がりそうだが、実際にはメモリ競合、通信のオーバヘッドなどで、数に比例した性能は期待できない。逆に、プロセッサが増えることによって性能が低下する場合すらある。

0 コメント:

コメントを投稿