前回までに,マイクロプロセサが性能を向上させていくための方向性を述べた。具体的には,VLSI集積度の向上という確実な技術動向を生かして,プロセサの動作速度と比べてはるかに長いメモリー・アクセスに要する時間(レイテンシ)をいかにうまく隠し,命令実行ユニットの待ち状態を減らせるかが性能向上の重要なポイントとなる。この目的を達成するためには,以下のような手法がある。

◆キャッシュの大容量化

 一般に,速度差がある2つのものを同期して動かすために必須となる手法がキャッシュである。このケースで言えば,マイクロプロセサとメイン・メモリーのあいだに比較的小容量の高速メモリーを置き,最近使用されたデーターを一時的に置いておくことで見かけ上,メイン・メモリーの遅延を隠そうという発想であり,現在のマイクロプロセサであれば必ず使用されているテクノロジである。特に,チップ上にキャッシュを置くオンチップ・キャッシュは有効である。前回述べたように,1回チップの外に電気信号を出すだけでも大きな遅延が発生してしまうが,オンチップ・キャッシュへはこのような遅延を伴なわずアクセスできるからである。

 キャッシュ容量を大きくして,キャッシュのヒット率を上げて性能を向上しようというのは単純ではあるが実は効果的な手法である。複雑なアーキテクチャ上の仕組みを使うよりも,深く考えずにキャッシュを大きくする剛腕的手法の方が有効なことも多いのである。実際,初期のRISCプロセサが同時期のCISCプロセサの性能を大きく凌駕(りょうが)できた理由の1つが,命令の単純化により論理ユニット部分がチップ上で占める面積を小さくできた代わりに大容量のオンチップ・キャッシュを置くことができた点にあった。

◆パイプラインの強化

 プロセサの命令の実行は,大きく,命令のフェッチ(読み込み),解釈,実行,結果の書き戻しという段階で行われる。当然,このすべての段階を完了するまで次の命令が実行できないのでは実行効率が上がらないので,ある命令が実行されているときには,その前の命令は解釈段階にあり,その前の前の命令はフェッチ段階にあるという,いわばバケツ・リレー的な設計が採られる。これがパイプラインであり,現在のマイクロプロセサであれば必ず使用されている技術である。

 このパイプラインの段数を細かくして各段階の処理を簡略化し,動作周波数の向上を目指しつつ,メモリーのレイテンシの影響を小さくしようという発想がスーパーパイプラインという発想である。良いことずくめのようであるが,実際にはやっかいな問題も多い。最大の問題は,条件分岐,要するにif文である。パイプラインでは命令をどんどん先読みしていくわけだが,条件分岐命令は実行してみないと次の命令をどこに読みに行けばよいのか分からないからである。

 この問題を解決するためには,パイプラインを複数設けて,分岐したときとしなかった時の両方の命令を先読みするなどの方法が採られる。また,とりあえず,先読みした命令を実行しておき,読みが外れて別の命令に分岐してしまった時はその結果を捨てる“投機的実行”と呼ばれる複雑なテクニックもある。パイプラインをあまり深くすると様々な副作用が発生し,その解決のためのハードウエアが複雑になってしまう。つまり,パイプライン強化による性能向上には限界があるということである。

◆スーパースカラー

 キャッシュの大容量化とパイプライン強化により,実行ユニットをほぼ常にビジーにすることが可能になったとしても,まだ高速化の余地はある。一般的なプログラムは直列的な命令の並びとして書かれているが,実際には複数の命令を同時並行的に実行できることが多いからである。いちばん簡単な例を挙げれば,下の命令列は,通常,1つずつ実行する必要はなく,もし実行ユニットが2つあるのならば2つ同時に実行してしまっても問題はない。

R1←R1+1  //レジスタ1の内容に1を加算
R2←R3*2  //レジスタ3の内容を2倍して結果をレジスタ2に格納

 スーパースカラーは,このようなプログラムの中にある並列実行可能な部分を検出し,複数の実行ユニットを使って同時並行的に稼働させる手法である。現在のマイクロプロセサではスーパースカラー技術の採用が当たり前になっている。

◆VLIW(Very Long Instruction Word)

 スーパースカラーのポイントは,ハードウエアがプログラムの命令列にある並列性を(コンパイラの助けを借りて)自動的に検知し,できる限り複数の命令を並行的に実行できるようにすることでスループットを向上させるということである。

 このようなハードウエアに頼る方法ではなく,命令の並列性の検出をコンパイル時に先にやってしまおうという発想もある。実行時の処理はプログラムの実行のたびに行わなければならないが,コンパイルにおける処理は1度だけやっておけばよいので効率性が高い。

 並列性の検知というやっかいな作業からハードウエアを開放することで,ハードウエアをより単純化し,結果的にキャッシュの大容量化やクロック周波数の向上も容易にしようという発想のアーキテクチャがVLIWである。VLIWはその名のとおり128ビット程度の長い命令フォーマットを持つ。コンパイラがソース・プログラムを解析して,同時並行的に実行可能な命令群をこの長い命令に詰め込むわけである。ハードウエアは,単純にこの長い命令を一気に実行してしまうことができる(実際には,話はこれほど単純ではないが,概念的にはそういうことである)。

 そして,Itaniumファミリの元となるEPIC(Explicit Parallel Instruction Computing)というアーキテクチャは,このVLIWの研究成果から多くを引き継いでいるのである。

 なお,米TransmetaのCruesoeチップではVLIWアーキテクチャが使用されているが,実際には,ソフトウエアによって実行時に米Intelのx86互換命令が動的にVLIWの命令に変換されるのでプログラマにとってVLIW命令が直接見えることはない。

◆ハイパースレッディング

 ここで,ちょっと視点を変えて,OSレベルでI/Oとメイン・メモリーの速度差を解消するためにどのような手法が使われているかを考えてみよう。あるプログラムがI/O要求を出し,物理的なI/Oが行われたとする。その時,プロセサはそのI/Oが終わるまでじっと待っているわけではなく,別の待機中のプロセスに処理を切り替えて実行を継続する。こうすることで,I/Oの大きな遅延があってもプロセサの待ち状態を最小化できる。マルチタスキングという周知の技術である。

 同じ発想をマイクロプロセサ・レベルで実行したのが,ハイパースレッディングである。つまり,メモリー・アクセスの遅延が発生した時に,実行中のプロセスを切り替え,実行ユニットをできるだけ待ち状態にさせないということである。ハイパースレッディングは,あまり大掛かりなロジックが必要ない(つまり,チップ上に占める面積が比較的小さい)わりに,それなりの効果が出せるテクニックである。

 ハイパースレッディングはPentium 4で実装されたことから広く知られることとなった。米Sun Microsystemsは同様の手法を「チップ・レベル・マルチタスキング(CMT)」と呼んでいるが,こちらの方がより直感的にわかりやすい名前かもしれない。

◇     ◇     ◇

 さて,これまでの3回の前置きを経て,ようやく次回Itaniumそのものについて触れられる準備ができた。ハードウエア・エンジニアの方にとってはちょっと物足りなかったかもしれないが,他の分野の方にとっては,マイクロプロセサ・アーキテクチャの勉強をする上で,良い取っかかりになったのではと期待する。

 もちろん,マイクロプロセサ・アーキテクチャの設計にはほかにも考えなければならないことは数多くある(たとえば,SIMD,ハザード,インターロック,マイクロデータフローなどなど重要なポイントを省略した)。大学の講義2学期分くらいの内容を4回連載の1万字で程度書こうとしているのでしかたがない話ではある。もし,この分野に興味をもたれた方は『コンピュータの構成と設計―ハードウエアとソフトウエアのインタフェース』などの書籍にアクセスしていただければと思う。