エントリー

コンピュータ基礎の基礎~スーパースカラプロセッサ

  • 2010/07/30 18:47
  • カテゴリー:備忘録

 さて,続いてスーパースカラプロセッサについてです。

 パイプライン,キャッシュ,そして仮想記憶と,コンピュータについて重要な基礎的技術についてはこの3日で勉強してきました。今回のスーパースカラや次のマルチプロセッサについては,必ずしも全てのコンピュータに入っているわけではなく,一般化したかどうかには意見が分かれるところがあると思います。

 しかし,技術的には完成の域に達しており,後は使うか使わないかだけの問題になっています。その点では基礎的な技術と言ってもよいかも知れません。

 パイプラインとキャッシュを使えば,1サイクルごとに1命令を実行出来るという,かなり理想的なところまで可能になることがわかりました。といいますか,RISCプロセッサというのは,命令を単純にして1命令を小さく作って,それをパイプラインに流して1サイクルで1命令を実行出来るようにしたプロセッサでした。

 しかし,1サイクルで1命令が実現してしまったわけですから,ここから先の高速化は今の構成では不可能です。だって,1サイクルで1命令以上を処理するには,処理する装置を1つから複数に増やさねばならない訳ですから。

 こうして,複数の命令を実行出来るようにパイプラインを複数に増やしたプロセッサを,スーパースカラプロセッサといいます。

 パイプラインが1本のプロセッサは同時に1命令しか実行出来ませんが,これはスカラプロセッサと呼ばれています。これを越えるものとして,複数命令が同時に実行出来る複数パイプラインのプロセッサを,スーパースカラプロセッサといいます。

 例えば,パイプラインが2本になれば,同時に実行出来る命令は2になりますから,単純に倍になりそうです。しかし残念な事に,順番にやってくる命令が,いつも同時に実行可能とは限りません。

 例えば,1つ目の命令の結果を2つ目の命令で使う場合など,どうしても順番に処理しないといけなくなります。

 実はスーパースカラプロセッサのキモというのは,命令の並列性を調べ,同時に実行出来そうな命令を並べるという技術に集約されます。

 そんな並列性は,コンパイル時に並べ替えておけばいいだろうという方,とても鋭いです。まさにその通りで,スーパースカラプロセッサは,シングルパイプラインのプロセッサとプログラムの互換性を持ちますが,コンパイルし直した方が高速に動作することは良くあることです。

 しかし,遅くとも古いソフトがコンパイル無しでもそこそこ高速に動くということはとても重要なことであり,いわば並列性を調べて並べ替えを行う仕組みをハードウェアで実装したのがスーパースカラプロセッサであり,コンパイラでやってしまったのがVLIWといってよいと思います。

 当然,スーパースカラプロセッサは巨大になり,複雑になりました。同時に実行出来る命令が1つから2つになれば2倍になっても,4個から5個に増えてもたった25%しか速くなりません。その上,パイプラインが増えるほど同時に実行出来る組み合わせは厳しくなり,回路規模は増大しクロックも上がらず,しかも結果として遊んでいるパイプラインが出てきてしまうこともあり得ます。

 こうして,一世を風靡したスーパースカラプロセッサは限界を迎え,現在は完成した技術として利用されているのです。

 では,スーパースカラプロセッサについて,もう少し詳しく見ていきましょう。パイプラインを複数並べて命令が同時に実行出来るということは,どのめいれいが同時に実行出来るかを判断し,必要に応じて命令の並べ替えを行うことが必要になります。前述のように,スーパースカラプロセッサというのは,これが最重要技術です。

 命令の順番を入れ替えて良い場合は,同時実行を行うことの出来るような組み合わせを作る事が出来ます。命令を順に実行することをインオーダ,命令の順を入れ替えることをアウトオブオーダといいます。

 しかし,命令が順番通りに実行されないと予期しない結果を招くことがあります。以下にその問題として3つのハザードを示します。

(1)リード・アフター・ライトハザード(RAW)
 読み出して利用したいレジスタの値が,先行の命令によって書かれたものであって欲しい場合に発生する問題です。書くのは先行の命令,読むのは後続の命令です。先行命令が書いた結果を後続命令が読んで利用するというのはよくあることですが,順番が変わってしまうと結果が出る前に読まなくてはいけませんから,これはどうにも回避不可能な問題で,命令の入れ替えは出来ません。

(2)ライト・アフター・ライトハザード(WAW)
 同じレジスタに2回の書き込みがあった場合,2回目の書き込みが残っていないといけないというものです。順番が入れ替わって1回目が後に書かれてしまうと,2回目の結果が上書きされますので,消えてしまいます。

(3)ライト・アフター・リードハザード(WAR)
 読み出して利用したいレジスタの値が,後続の命令によって変更される前のものであって欲しい場合に発生する問題です。書くのは後続の命令,読むのは先行の命令で,RAWハザードとは逆になります。順番が入れ替わると,先行の命令が使う値が後続の命令によって変わってしまう可能性があるわけです。

 このうち,(1)は命令の順番が変わってしまうと回避不可能,(2)と(3)については,レジスタリネーミングを使って回避が可能です。

 そのレジスタリネーミングというのは,レジスタの名前を付け替えることです。実際にはレジスタの数を増やして実現しますが,プログラムを書く人から見てレジスタが増えたわけではないので,リネーミングといいます。

 レジスタリネーミングを使うと,(2)は同じレジスタにせず異なるレジスタに書き込むようにし,命令の順番通りに結果を使うようにすれば回避できます。

 (3)についても同様で,リネームして異なるレジスタを相手にして動いてもらい,最終的に命令の順番通りに読み出せば,結果が出るまでの途中の順番が入れ替わっても問題はありません。

 こうして,レジスタリネーミングを用いれば,(1)のRAWハザードだけを考慮すれば,(2)と(3)は解決出来たことになります。つまり,レジスタを2つ用意して結果をどちらも潰さず残しておき,利用するときに書き込み前の値が欲しければ古い方を,書き込み後の値が欲しければ新しい方を読み出して使うという仕組みです。


 こうして,順番を入れ替えて実行することがある程度出来るようになりました。ここで,命令の実行が完了する時刻に注目すると,命令によって時間のかかるものとかからないものがあるわけですから,当然終わる時刻が同時とは限りません。そこで,命令の処理が開始された状態を発行,処理が終わった状態を完了と決めて,それぞれインオーダとアウトオブオーダと組み合わせます。すると,

 インオーダ発行
 インオーダ完了
 アウトオブオーダ発行
 アウトオブオーダ完了

 の4つの組み合わせが出来ます。


・インオーダ発行

 これはもっとも単純で,命令キューに入っている連続する命令が同時実行可能かどうかを判断するだけです。もし命令に依存性があり,同時実行出来ない場合には,1命令のみを発行します。

・アウトオブオーダ発行

 アウトオブオーダ発行の場合は,命令の順番が入れ替わって発行されるわけですから,命令キューに入っている命令の全てで依存性が調べられます。冷静に考えると,命令キューに入っている命令のオペランドを,互いに使っていないかどうかをざっと調べるだけでよいことになります。もし依存性が全ての命令であった場合は1命令のみを発行します。

・アウトオブオーダ完了

 スーパースカラプロセッサとしては最も完璧なものになりますが,命令を完了する順番さえも入れ替わっていてよい,ということですので,もうなんでもありです。しかし,命令の完了順番が違ってくると,ライト・アフター・ライトハザードが発生してしまいます。

 これはレジスタリネーミングで回避できるとしても,実は例外や割り込みのを考えるた場合,順番が入れ替わってしまうと優先順位が変わってしまうことと同じになり,大変まずいですから,実はこのアウトオブオーダ完了という仕組みは一般的には使用されません。

・インオーダ完了

 これは結果の出る順番を入れ替えないわけですから,早く終わった命令が遅い命令を待ってあげればいいだけのことです。先に出た結果をROB(ReOrder Buffer)と呼ばれるバッファに取り込んでおき,結果の順番を守るわけです。これだと,アウトオブオーダ完了で問題となった例外や割り込みの問題は発生しません。

 ということで,スーパースカラプロセッサには,現実的には,インオーダ発行でインオーダ完了のインオーダ型と,アウトオブオーダ発行でインオーダ完了のアウトオブオーダ型の2種類しかない,ということになります。


 スーパースカラプロセッサの場合,シングルパイプラインのプロセッサに比べて,時間的な前後関係が問題になることがわかります。従って,単にパイプラインを乱さないようにしていれば良かった話が,依存関係を崩さないという絶対に守らなければならないことを考慮しなくてはならず,大変難しくなります。

 例えば,遅延分岐で済ませていた分岐のペナルティも,スーパースカラでは分岐予測と投機実行を組み合わせるのが普通です。

 分岐予測には3つの種類があり,分岐しないと決め打ちする単純予測,プログラムの走っている向きに逆行する場合はループの終端だから分岐すると決め打ちし,順行する場合は分岐しないと決め打ちする静的な分岐予測,分岐回数と分岐先の履歴から次の分岐を予測する動的な分岐予測があり,後者の方がヒット率が高いと言われています。動的な分岐予測には様々な方法があり,現在では90%を越えるようなヒット率を実現している例もあります。

 投機実行は,その分岐予測の結果が出る前に命令をとりあえず実行してしまうのですが,当然外れることもあるわけで,その場合はやり直しになります。しかし,どうせ分岐先が決まるまで待ち時間が出てしまうわけですから,その間にとりあえず命令を実行しても,無駄にはなっていません。

 スーパースカラプロセッサは,確かに複雑さと性能向上のバランスが限界に達して,これ以上大きな進歩はないと思いますが,なにも闇雲にパイプラインの数を増やすことをしなくても,時間のかかる浮動小数点演算と整数演算を並列に同時実行するだけでもそのメリットは大変に大きく,コンパイラによる命令の並べ替えと併用し,今後のプロセッサに必須な技術になっていくと思います。

ページ移動

ユーティリティ

2020年05月

- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -

検索

エントリー検索フォーム
キーワード

ユーザー

新着画像

新着エントリー

過去ログ

Feed