リオーダバッファを用いる方式

ここまでは、大きな物理レジスタファイルを持つリネーム方式を説明してきたが、リオーダバッファを用いる方式では、論理レジスタと1対1に対応するアーキテクチャレジスタファイルと、仕掛り中の命令の演算結果を保持するリオーダバッファ(Re-order Buffer)と呼ぶ別個のレジスタファイルを用いる。

この方式では、命令デコード時に、結果の格納先としてリオーダバッファのエントリを割り当てる。一方、レジスタリネーム表は、ほぼ、同じで、各レジスタがアーキテクチャレジスタファイルのどのエントリを指すか、あるいは、リオーダバッファのどのエントリを指すかの情報を保持する。そして、後続の命令のデコードに当たっては、レジスタリネーム表を見て、アーキテクチャレジスタファイルからオペランドを読み出すか、仕掛り中の命令の結果を受け取る場合には、そのリオーダバッファのエントリ番号をタグとしてリザベーションステーションのPRs部に格納する。

リザベーションステーションは、タグの一致で依存関係にある命令の結果を受け取り、オペランドが揃ったら実行を開始し、演算が終わると、格納するリオーダバッファのエントリ番号をタグとしてつけてリザルトバスに載せるのは、前に述べた方式と同じである。

図6.23 リオーダバッファ方式の構成

前述の方式との大きな違いは、図6.23の中に赤線で示したパスを使って、命令のコミット時にコミット機構のエントリからリオーダバッファのエントリ番号と論理レジスタ番号を得て、リオーダバッファからデータを読出し、アーキテクチャレジスタファイルに書き戻しを行うという点である。また、この時点で使用していたリオーダバッファのエントリをフリーリストに戻す。このリオーダバッファを使う構造でも、命令のコミットはインオーダに行われるので、アーキテクチャレジスタ状態の更新は順次実行と同じインオーダになる。

なお、図を簡単にするため、図6.23ではアーキテクチャレジスタファイル、リオーダバッファともにオペランドの読出しは1命令分の2ポート、リオーダバッファからアーキテクチャレジスタファイルへの書き戻しパスを1本としているが、リザベーションステーションの数と1サイクルで並列にコミットする命令数に応じたリード、ライトポートが必要となる。

リオーダバッファ方式では、このリオーダバッファからアーキテクチャレジスタへのデータの書き戻しという、前の方式では不要な操作が必要となるが、一方、割り込みなどが発生した場合は、リオーダバッファとリザベーションステーションの全エントリをクリアし、レジスタリネーム表は、全エントリがそのままアーキテクチャレジスタファイルの対応するエントリを指すというイニシャル状態に戻してしまえば、状態の復元ができてしまう。したがって、フリーリストとレジスタリネーム表の巻き戻しのためのハードウェアや、操作は不要であるというメリットがある。

また、回路的には、巨大なレジスタファイルはアクセスタイムが長くなり、クロック向上の制約になりうるが、これをアーキテクチャレジスタファイルとリオーダバッファという2つのレジスタファイルに分割することにより、アーキテクチャレジスタファイルのライトポート数が減る、個々のレジスタファイルのエントリ数が減り、ある程度、アクセス速度を改善することができるというメリットもある。一方、リオーダバッファは、命令を発行するためのリードポートに加えて、コミットした命令の結果を読み出してアーキテクチャレジスタファイルへ書き戻すためのリードポートが必要となり、ポート数が増大するという問題がある。

レジスタリネーミングによりOut-of-Order実行を行う方式としては、前述の大きな物理レジスタを用いる方式と、ここで述べた、アーキテクチャレジスタとROBのペアを用いるというのが2つの基本的な方式であるが、細部においては、ここで説明したやり方以外に多くのバリエーションがある。ここではリネームされた結果格納レジスタのValidビットをレジスタ側に設けたが、このビットはレジスタリネーム表に持っても良い。

さらに、命令の結果のインオーダ並べ替えに関して、本稿で説明したコミット機構は制御情報の並べ替えを担当し、ROBはデータの並べ替えを担当するものであるが、両者をあわせて1つのROBにするという構成も可能である、などなど、多くのバリエーションがある。