書籍“プロセッサを支える技術 -果てしなくスピードを追求する世界”を読んで

はじめに

表題の書籍を読みましたので、それについて書いてみたいと思います。該当する書籍の情報は以下の通りです:

本書を読んだ目的と感想

私はソフトウェア側の人間なので、プロセッサー内部のことについてはソフトウェアを書く際に透けて見える部分くらいしか基本的には知りません。そこでこの部分を補う目的で本書を購入して読んでみました(同じ目的では「TECH I シリーズ Vol.20 / マイクロプロセッサ・アーキテクチャ入門 -RISCプロセッサの基礎から最新プロセッサのしくみまで / 著・中森 章 / CQ出版社」を発売直後くらいに読んだことがあります)。

内容は現在のコンピューターの構造と基本的な解説から始まります。そしてその後にそれ以前の計算機の歴史へのつながっていきます。最初は機械式、その後だんだんと電子式へつながっていき、トランジスター素子や集積回路へと移り変わり、そして現在のプロセッサーの処理の仕方へ話は続いていきます。このように飽きさせず、また無理のない展開で最初から最後までさらっと読める1冊となっています。

カバー範囲はパイプライン以前、パイプライン導入、アウトオブオーダー、それに関連する各種技術(レジスターリネームなど)の解説、シングルプロセッサーからマルチスレッド、マルチプロセッサーへの移り変わり、キャッシュコントロールとマルチプロセッサーでのキャッシュコヒーレンシーについてや仮想化、OSなどのソフトウェアとの関係など、一通りの内容がまとまっています。

本書は一般のソフトウェア技術者やCPUなどのプロセッサーの中身について詳しく理解をしたい、いわゆる自作パソコン上級者にお勧めできる1冊です。

気になった点

そのうえで、少し私としては気になる点もありました(※サポートページに記載のあるものは除きます):

P.29

なお、本来のASCIIコードは0x00~0x7fの範囲ですが、日本では、$(ドル)記号を¥(円)記号に、~(Tilde)を ̄(Overline)に変更し、また、0xA0以降に半角カナを追加した図1.11のJIS X 201コード表が用いられています。

$(ドル)記号ではなく、\(バックスラッシュ)の誤りです。

P.39

注24 XXビットアーキテクチャという場合、メモリ空間の指定がXXビットである、ということを意味します。たとえば「64ビットアーキテクチャ」といった場合、メモリ空間が264バイトあることを指します。現実的にはプロセッサのアドレスパスやデータパスもアドレス計算を行うために64ビット対応が必要となるため、それに付随して演算器やレジスタも64ビットに対応した設計が為されています。

4ビットアーキテクチャのIntel 4004は12ビットメモリ空間、8ビットアーキテクチャのIntel 8008/Zilog Z80は16ビットメモリ空間、16ビットアーキテクチャのIntel 8086は20ビットメモリ空間、同Intel 80286は24ビットメモリ空間、32ビットアーキテクチャのMC68000は24ビットメモリ空間(現在のMotorolaから分離した半導体部門のFreescaleの資料では32ビット扱い)、同Intel 80386SXは24ビットメモリ空間などの実例がある以上、このまとめ方は問題があるのではないかと思います。

P.40

AMDが先行して2000年にAMD86-64と呼ぶ64ビット拡張アーキテクチャを発表し、その後、Intelもこのアーキテクチャに相乗りすることになりました。

「AMD86-64」ではなく「AMD x86-64」が正しいです。

発表時期は見解によると思いますが、最初にAMDが概要を発表したのは1999年10月4日(米国時間)です(参考:「Microprocessor Forumレポート AMDが64ビットアーキテクチャ「x86-64」の概要を発表PC Watch」)。その後、プログラミング用の仕様を発表したのが2000年8月10日(米国時間)です(参考:「AMD、X86-64アーキテクチャのプログラミングガイドを公開PC Watch」)。

個人的には発表は1999年の方でいいのではないかと思うのですが、いかがでしょうか?

P.43

「コンパイラを使う高級言語によるプログラミング」~「インタプリタによるプログラミング」の内容が根本的におかしいです:

  • C#はコンパイラ言語、Javaはインタプリタ言語に分類していますが、これは同一の分類になるべきです。この分類にする意味がわかりません。
  • C#のMSILのコードは仮想マシン方式なので他環境(例えばMono)でも実行できます。この特性はJavaと同様のものです。
  • 「インタプリタの場合は高級言語記述の文字列をそのまま入力して実行する」というのであれば、Javaをインタプリタにするのは誤りです。

念のため、何を意図したのかこれを書きながら考えてみたのですが、もしかすると「JavaScript」を「Java」と書いている可能性が思い浮かんできたのですが、いかがでしょうか? であるならば「Java」という表記は誤りなので「JavaScript」に訂正すべきだと考えます。

P.126

このため、3.3節で述べる「Prefix」を使って拡張した命令を必要とする64ビットモードでの32ビットデータのアクセスの場合には、命令デコードが制約となって性能が落ちることがあります。

これはREXプリフィクスのことを指していると思われます。であるとすると、64ビットモードで64ビットデータのアクセス時に必要になるので、この記述は誤りです。同書でもP.194で

REX Prefixを付けると基本の8本の汎用レジスタを拡張された8本の基本レジスタの指定に読み替え、オペランドのサイズも8バイトと読み替えます。

と記載があるため、この点は理解されているものと思われます。それを考えると前者はやはり誤った記述であるように思います。

P.162

大きな違いは、メモリ空間の場合は通常のメモリアクセスと同じで高級言語でもアクセスできるのですが、I/O空間の場合はI/O空間をアクセスする命令を使う必要があり、通常はアセンブラによるプログラミングが必要になります。

ここは見解が分かれる部分だと思いますが、私の認識としては一般に任意のメモリ空間にアクセス可能な高級言語であれば、マクロやライブラリなどによってI/O空間にもアクセスできるものが一般的であると考えています。

P.177

また、一般のプログラムがI/Oなどの処理をOSに依頼するときには、ソフトウェア割り込みという特別なトラップが使われます。

これはWindowsのことなのかLinuxのことなのか、またそのバージョンによって状況が異なります。Windowsの場合には2000まではソフトウェア割り込みを使用していましたが、Windows XPからはx86版ではSYSENTER、x64版ではSYSCALLに変更されています。Linuxの場合はx86ではソフトウェア割り込みですが、x86-64ではSYSCALLです。

これはどのOSのどのバージョンを念頭に説明しているのかが不足していると思いますので、それを文中に含めた方がよかったかと思います。

P.189

IA-32eモードの説明の中での以下の説明部分:

現状では両方のモードが使われており、32ビットのWindows OSはCompatibilityモードで動作しており、64ビットWindows OSは64ビットモードを使っています。

32ビットのWindows OSはIA-32eモードではなくLegacyモードで動作するものですから、この記述は誤りです。

P.193

この指摘は私と著者での見解の相違の範疇かもしれません。

「図3.7.1 x86プロセッサの64ビットモードの命令形式」の図では、オプショナルになるものの記載が不足しています。「Mod R/M」と「SIB」には必要に応じてと明記しているのですから、「Prefix」「REX Prefix」もオプショナルであることを明記すべきだと思いました(※本文中では「これらのPrefixのサイズはすべて1バイトで、その機能が必要ない場合には付ける必要はありません。」と記載されています)。

また、「Prefix」の説明で「①最大4つの従来からのPrefix」という説明は誤りだと考えます。「最大4つ」の部分は、正しくは「4グループ」であるべきです(※本文説明中では「4グループ」と説明しています)。

Intelによるプレフィクスを含む命令フォーマットの解説図は以下のようになっています:

IA-32eモードにおける命令フォーマット

Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Combined Volumes:
1, 2A, 2B, 2C, 3A, 3B and 3C

Order Number: 325462-048US
September 2013

447ページ「Figure 2-3. Prefix Ordering in 64-bit Mode」より引用

P.267

「■マルチソケットシステムとメモリ」において、いくつか方法があるとはしているものの代表的なメモリへのアドレス割り付けとしてノードインターリーブ(Node Interleaving)のみが紹介されていることが引っかかりました(本書で説明されているこの方式がノードインターリーブだという説明はありません)。実際にはノードインターリーブと(cc)NUMAのいずれかというくらい、2大勢力だと思いますので、後者についても一応は触れた方がよかったのではないかと思います。

というのも、現在はWindowsもLinuxもカーネルレベルでNUMAがサポートされているからです。NUMAの最適化をミドルウェアやアプリケーションレベルで行える場合にはNUMAを選択することもあるので、言及の優先度はかなり高いはずだと思うのです。

P.344

このシステムのピーク性能が2.331FLOPSで、LINPACKの計算で1.759PFLOPSを達成しています。

「2.331FLOPS」は「2.331PFLOPS」の記述ミスですね。

まとめ

気になった点を細かく書いたのでネガティブなイメージを抱いてしまった方もいらっしゃるかもしれませんが、前述したように本書は読む価値のある本です。そうでなければこんなに細かくあれこれ気になるほどしっかり読んだりしません。この分野に興味のある方には自信を持ってお勧めする1冊です。

マジメに読んだせいで、私の購入した本はこんな姿になっています:

付箋でライオン状態になった本書

付箋紙だらけです。この付箋紙にはいろいろと思ったことや、気になったこと、コメントなどが書いてあります。きれいに読みつつ、書きたいことは書くという、私の読書スタイルです。

2013年11月04日追記

本書の内容についてより具体的に言及するように変更しました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です