レジスタ・ウィンドウ
レジスタウィンドウとは、コンピュータのCPUの一般的な動作であるプロシージャコールの性能を向上させる技法である。
この問題にハードウェアをつぎ込むことによってほとんど全てのコンピュータプログラムが高速に動作するようになる。これはバークレーRISCの設計上の特長のひとつであり、後にSPARC、AMD 29000、Intel i960で商用化された。
多くのCPUの設計では、レジスタと呼ばれる小規模な超高速メモリを持っている。レジスタは、長い命令列を実行中にCPUが一時的に値を保持しておくのに使われる。レジスタが多ければ性能が向上するが、レジスタというのはCPUの命令セットと密接な関係がある。一度CPUをリリースしてしまったら簡単にはレジスタを増やしたり出来ない。
レジスタは万能の性能向上策であるが、問題もある。コンピュータプログラムの別々の箇所はそれぞれ一時的な値を持っているため、レジスタの使用が競合してしまう。プログラムが実行時にどう動くかをよく理解することは困難である。開発者が実際に開発中に、自分が書いているコードがどれだけレジスタを使ったらよいか、どれだけをプログラムの他の部分のために残しておいたらよいかを決めるのは容易ではない。一般にそのような考慮は無視され、開発者あるいは彼らが使うコンパイラは見えている全てのレジスタを使うものである。
ここにレジスタウィンドウの使い道が出てくる。プログラムの各部はそこだけで使えるレジスタを必要とするので、プログラムの各部分ごとにレジスタのセットを提供することに意味が出てくる。もちろん、レジスタのセット以外のレジスタもプログラムのある部分から見えるなら、それも使われてしまうだろう。ここでのトリックはあるレジスタセット以外のレジスタを見えなくしてしまうことにある。これは何か複雑なことのように聞こえるかもしれないが、実際は単純である。プログラムのある部分から別の部分へプロシージャコールで移動するとCPUは簡単にそれを検知できる。一般にプロシージャコールはいくつかの決まった命令列で構成され、元に戻るときも決まった命令列を使う。バークレーの設計では、プロシージャコールの命令列によって新たなレジスタセットがそれまでのレジスタセットと入れ替えられる。また、プロシージャから元の場所に戻るときは、それまで使っていたレジスタセットに"dead"(あるいは"reusable")という印をつける。
バークレーRISCの設計では、全部で64本あるレジスタのうち 8本がプログラムから見えるようになっている。レジスタ全体のことをレジスタファイルと呼び、8本のレジスタのことをウィンドウと呼ぶ。このレジスタファイルによれば、最大で8レベルのプロシージャコールがレジスタファイル内で実行可能である。プログラムが8レベル以上の深さでプロシージャをコールしない限りレジスタがあふれる(つまり主記憶かキャッシュに追い出される)ことはない。レジスタがあふれたときの処理はかなり時間を要する。ほとんどのプログラムは6レベルまでの深さの範囲内で処理を行う。
比較のためサン・マイクロシステムズのSPARCアーキテクチャを説明する。こちらの場合、8本のレジスタのセットが4個同時に見えるようになっている。そのうち3セットがウィンドウとなっている。
- i0 - i7 の8本のレジスタは現在のプロシージャへの入力レジスタ(つまり引数)
- L0 - L7 の8本のレジスタはローカルに使用
- o0 - o7 の8本のレジスタは次のレベルのプロシージャに渡す出力レジスタ
あるプロシージャがコールされたときレジスタウィンドウが16本ぶんずらされて、コール元の入力レジスタとローカルレジスタを隠し、元の出力レジスタを新たな入力レジスタとする。ウィンドウ化されていない8本のレジスタ(g0 - g7)はどのプロシージャからも見えるようになっている。
AMD 29000ではウィンドウのサイズを可変にしている。というのは一般にほとんどのプロシージャの引数は8個より少ないため、可変にすることでレジスタを無駄遣いしなくなるのである。また、29000ではグローバルなレジスタ64本とウィンドウ用レジスタ128本を持っている。
レジスタウィンドウはアップグレードも容易である。レジスタを追加してもプログラムからは見えないので、ウィンドウを追加することはいつでもできるのである。ところで、オブジェクト指向プログラミングでは、通常よりも小さなプロシージャコールが多く発生する。これに対しては例えばウィンドウの数を8から16に増やすことで対応できる。SPARCではそのようにして対応し、新たな世代のアーキテクチャではレジスタウィンドウ数が増えている。そのため、レジスタウィンドウがオーバフローすることが少なくなった。
レジスタウィンドウは性能を向上させる唯一の方法ではない。スタンフォード大学のグループはMIPSアーキテクチャを設計したが、彼らはバークレーのやっていることを見てレジスタ数が不十分なのではなく、使い方が問題なのだと判断した。彼らはコンパイラの研究に時間を費やし、MIPS命令セットとレジスタを完全に使いこなすコンパイラの完成を目指した。 これによりレジスタ数を半分にしてチップをより単純化し、ひとつのプロシージャが使うレジスタ数を減らさずに性能を向上させた。最終的に、現代的なコンパイラによってMIPSはプロシージャコールの際にもレジスタを有効に使うことに成功した。