R4000

R4000は、MIPS III命令セットアーキテクチャ  を実装したマイクロプロセッサで、ミップス社が設計した。1991年10月1日に正式発表された。64ビットのマイクロプロセッサとしては最初期のもので、MIPS III を最初に実装した。1990年代初期、RISCマイクロプロセッサは Intel486 などのCISCマイクロプロセッサに取って代わることが期待され、R4000はRISCプラットフォームの業界共通規格である Advanced Computing Environment  で使用するマイクロプロセッサに選ばれた。ACE自体は様々な要因が重なって失敗に終わったが、R4000 はワークステーションやサーバ市場で成功を収めた。

1. 概要
-----

R3000に比較して、以下のような強化がなされている。

FPUを内蔵
64ビット対応のレジスタセットと命令セット
8段のパイプラインで、システムクロックの倍のクロックで動作する。
動作周波数は100MHzと150MHz
二次キャッシュメモリをサポート
マルチプロセッサ対応の命令とキャッシュR4000はバリエーションとして以下のものがある。

R4000PC 二次キャッシュへのインタフェースを削除してピン数を減らしたバージョン。
R4000SC 二次キャッシュを接続可能なバージョン。
R4000MC 二次キャッシュ・インタフェースに加えてマルチプロセッサ対応インターフェイスを備えたバージョン。ただし、内蔵キャッシュは命令 8Kバイト、データ 8Kバイトであり、R3000よりも小さくなっている。ほとんど間をおかずに内蔵キャッシュ容量を倍増したR4400をリリースしている。 スーパーパイプラインの割りには動作周波数が低く、スーパースカラも採用していないため、他社CPUに遅れをとるようになった。これは自社工場を持たず、設計と製造が分離されたことによるオーバーヘッドによるものと見るものもある。 その後、R10000などにより、第一線級CPUファミリーへの復帰を図ったが、ある程度先端的なラインと製造技術を要求するため、製造できるメーカが限られる結果となり、競争力をさらに低下させる遠因ともなった。

とは言うものの、R4000/R4400はワークステーションやサーバに広く使われた。また、派生品の R4100、R4300、R4600などは組み込みシステムで多く使われている。

2. アーキテクチャ
----------

R4000は、パイプラインの段数を8段にしてひとつのステージの処理量を減らし、動作周波数を向上させた。プロセッサのアーキテクチャ上の改善は実はそれだけであり、分岐予測もアウト・オブ・オーダー実行も投機的実行もレジスタ・リネーミングもこの段階では全く採用されていない。それよりも、設計上の主眼はマルチプロセッサ対応機能のサポートと64ビット化に置かれている。

細かい機能の改善点としては、以下のような点が上げられる。

branch likely 命令の追加。条件分岐命令では次の命令が必ず実行された上で分岐すべき状態ならば分岐していた。branch likely命令では分岐するときだけ次の命令を実行し、分岐しないときは実行しないという動作をする。これを使うと、分岐先を2命令先にしておけば、実質的に分岐で実行されるのは次の命令だけとなり、パイプラインを乱さずに条件付動作を実現できる。
浮動小数点演算では、平方根を求める命令が追加された。
TLBは 48エントリと減っているが、1エントリで物理ページを2ページマップすることができるようになっている。したがって、実質的には96エントリに増えているとも言える。
また、ページサイズが4Kバイト固定から、4K～16Mバイトまで可変となった。たとえばX Window Systemのサーバプロセスがフレームバッファを16MバイトのページでマップすることでTLBの浪費を防ぐことができる。

2.1. 64ビット・アーキテクチャ
------------------

64ビットモードでは、汎用レジスタが全て64ビット幅となり、アドレスに関連する情報を格納するCP0レジスタも64ビット化された。各種演算は64ビット版が用意されている。メモリ管理ユニット  は48エントリのTLBを使って仮想アドレスから物理アドレスへの変換を行う。仮想アドレス空間は64ビットとなっているが、実はフラットではない。実際には40ビット、すなわち1TBの仮想記憶空間しか実装していない。それ以外のビットはゼロであることを確認するだけとなっている。物理アドレスは36ビットで、物理メモリ空間は64GBまでとなっている。また、特筆すべきは特権モードとしてカーネルモードとユーザモードの中間のスーパーバイザモードが導入された点である。この図の中で //xkphys// は説明が必要であろう。//xkphys// は物理空間をTLBを使わずにマップしているが、サイズは物理空間 64GBよりもずっと大きい。これは、従来の //kseg0// と //kseg1// を拡張したものであり、キャッシュコヒーレンシをどういう方式で保つかによって物理空間を多重にマップしているためである。//xkphys//にカーネルをおく場合、キャッシュコヒーレンシの方式によってアクセスすべきアドレスが異なる。

2.2. マルチプロセッサ対応
---------------

マルチプロセッサをサポートするにあたって、重要な点のひとつはキャッシュコヒーレンシである。R4000MC/R4400MCでは、スヌープ方式が採用されており、無効型プロトコルも更新型プロトコルも選択できるようになっている。

もうひとつ、マルチプロセッサで重要となるのは、並行して動作するスレッド間の同期をとる機構である。MIPSでは以下のふたつの機構で同期をとる。

sync命令 はメモリアクセスの順序性を保証する。たとえば、あるデータを更新したら、更新完了を示すフラグを立てるとする。その順番がTLBやキャッシュの状態に左右されて期待した順番にならないと更新していないものが更新されたように他のプロセッサから見えてしまう。これを防ぐのがsync命令である。まず、プロセッサXが次のようなコードを実行する。

sw t3, DT1 li t4, 1 sync sw t4, FL1

ここで、DT1が更新されたことをFL1で示す。一方プロセッサYは次のようなコードを実行する。

loop: lw t5, FL1 beq t2, zero, loop nop sync lw t6, DT1

これによって順序性を保つ。sync命令はマルチプロセッサでない場合でも、I/Oデバイスへの書き込みの完了を保証する目的で使うことができる。

ll/sc命令 ll命令はロード命令として動作するが、その際にロードアドレスをCP0のレジスタ LLAddr に格納しておく。その後でロードした内容に変更を加え、sc命令で元のアドレスに書き込む。ただし、sc命令は以下のように動作する。

まずLLAddrに格納されているアドレスとストアしようとしているアドレスが同じかどうかチェックする。違う場合は失敗したとしてストア元のレジスタに 0 を格納して終了する。
次に該当するキャッシュラインの状態をチェックする。これによって他のプロセッサがそのキャッシュラインに該当するメモリアドレスに書き込みを行ったかどうかがわかるので、もし書き込まれていたら失敗したと判断して、ストア元のレジスタに 0 を格納して終了する。
成功すれば、メモリに書き込みを行ってストア元のレジスタに 0 以外を書き込んで終了する。なお、LLAddr は例外が発生した場合もクリアされる。これを使うと、単純なスピンロックも、リーダー・ライターロックも実現可能である。スピンロックのコードは以下のようになる。

Loop: ll t2,  ; t1 の指すアドレスからロックワードを読み込む(0:未ロック 1:ロック済み）