アウトオブオーダー実行

アウトオブオーダー実行の処理フローや、アウトオブオーダ―実行のキーポイントの1つであるレジスタ・リネーミングの動作を記載します。


アウトオブオーダー実行の処理フロー

最近の命令キャッシュやデータキャッシュを内蔵した高性能なマイコンの命令処理は、アウトオブオーダー実行が採用されているものが多い。マイコン内の処理フローのイメージは下図の通りで、左端の「命令フェッチ」に始まり、右端の「メモリFix」で終了する(参考…処理フローが、「命令フェッチ」のようにステージに分かれている構造をパイプラインと呼ぶ)。
特に赤字の処理が、アウトオブオーダー実行のキーポイントになる。なお、赤字の処理がないマイコンの処理はインオーダー実行と呼ばれる。

下図の左端からの処理内容は以下の通り。
・「命令フェッチ」は、命令キャッシュ(マイコンに内蔵された命令専用の高速メモリ)から命令をマイコン内に取り込む。
・命令が分岐命令ならば「分岐予測」で分岐する/しないを決定する。なお、このステージはあくまで予測なので予測が間違っていたとわかったら正しい分岐をやり直す(分岐予測は無駄だったということになる)。
・「レジスタ・リネーミング1」は、前後の命令の依存関係を解決するため、レジスタ名を書き換える。こうすることで後続の処理でプログラムの順に関係のない命令を実行することが可能になる。
・「レジスタ・フェッチ」は、レジスタを取り込む。ここまでが命令を実行するための準備。
・あとは、命令の種類によって「整数演算」「浮動小数点演算」「ロード/ストア」「分岐/ジャンプ」のいずれかが実行される。なお、下図では各実行ユニットが1ステージしか書いてないが、実際は、複数のステージからなる場合もある。例えば、「整数演算」は1ステージ、「ロード/ストア」のロード処理はデータフェッチとデータアラインの2ステージからなる。
・次の「レジスタ・リネーミング2」は、「レジスタ・リネーミング1」で書き換えたレジスタ名を元に戻す。なお、処理フローを理解頂くため「レジスタ・リネーミング1」や「レジスタ・リネーミング2」に分けているが、実際は「レジスタ・リネーミング」という1つの機能がレジスタの書き換えや復帰を管理している。
・「レジスタFix」「メモリFix」で、プログラムの順にレジスタやメモリが書き込まれ、命令の処理が完了する。

補足1…「レジスタ・リネーミング1」でレジスタ名を書き換えるが、マイコンが持つ書き換え用のレジスタは有限なので、できるだけコンパイラの最適化のオプションを使って、前後の命令の依存関係をなくした方が良い(コンパイラができるだけ異なるレジスタを使う)。

補足2…アウトオブオーダー実行を採用するマイコンは命令キャッシュやデータキャッシュも採用する。キャッシュ上に命令やデータがないと(キャッシュにヒットしないと)アウトオブオーダー実行が発揮されないので、命令やデータをプリフェッチするなど、できればひと工夫した方が良い。

図.アウトオブオーダ―実行の処理フロー

レジスタ・リネーミングの動作

2waySuperScalar(2個の命令を同時に実行可能)を採用し、命令キャッシュやデータキャッシュを内蔵したアウトオブオーダー実行のマイコンで、下記プログラムを実行した際の「レジスタ・リネーミング1」の動作を記載する。

LD r2, 0x0(r3) //レジスタr3が指すアドレスからデータをr2にロード
ADDI r2, r2, 0x20 //レジスタr2に0x20を加算
SLL r2, r2, 0x16 //レジスタr2を左に16bitシフト
SD r2, 0x0(r3) //レジスタr3が指すアドレスにr2のデータをストア

LD r2, 0x0(r11) //レジスタr3がr11に変わっただけで処理は上記と同じ
ADDI r2, r2, 0x20
SLL r2, r2, 0x16
SD r2, 0x0(r11)

上記プログラムの場合、命令間でr2の依存関係があるため、プログラム順にしか処理できない(2個の命令を実行できる2waySuperScalarを活用できない)。レジスタ・リネーミングがあると、下記のようになる。なお、rr1はマイコン内にあるレジスタ・リネーミング専用のレジスタと考えて欲しい。

LD r2, 0x0(r3) //レジスタr3が指すアドレスからデータをr2にロード
ADDI r2, r2, 0x20 //レジスタr2に0x20を加算
SLL r2, r2, 0x16 //レジスタr2を左に16bitシフト
SD r2, 0x0(r3) //レジスタr3が指すアドレスにr2のデータをストア

LD rr1, 0x0(r11) //レジスタr3がr11に変わっただけで処理は上記と同じ
ADDI rr1, rr1, 0x20
SLL rr1, rr1, 0x16
SD rr1, 0x0(r11)

マイコンとしては、r2をrr1に書き換えたことで、r2の依存関係がなくなるため、アウトオブオーダ―実行で★部分の位置で命令を実行できるようになり、
・「LD rr1, 0x0(r11)」と「SLL r2, r2, 0x16」
・「ADDI rr1, rr1, 0x20」と「SD r2, 0x0(r3)」
を2個同時に実行できるようになる(2waySuperScalarを有効活用できる)。

LD r2, 0x0(r3)
ADDI r2, r2, 0x20
LD rr1, 0x0(r11) ★
SLL r2, r2, 0x16
ADDI rr1, rr1, 0x20 ★
SD r2, 0x0(r3)
SLL rr1, rr1, 0x16
SD rr1, 0x0(r11)

この記事が気に入ったらサポートをしてみませんか?