ITmedia NEWS > STUDIO >
ニュース
» 2020年05月11日 10時42分 公開

RISCの生い立ちからRISC-Vまでの遠い道のり:RISCとCISCの境目がなくなる Pentium Proの逆襲 (2/3)

[大原雄介,ITmedia]

 「Microcode」といわれて「?」と思われるかもしれないが、ごくごく初期のCPU(それこそi4004とかMC6800とか)はともかく、80386やMC680x0クラスともなると命令セットはかなり複雑で、これの解釈を文字通りハードウェアだけで実装するのはかなり困難であった。ちょっと前のところで書いたIntel i486は、極限まで速度を上げるために、このデコードを本当にハードウェアだけで実装(Hard Wired)した例だが、これで懲りたのか、続く製品ではこんなむちゃなことはしていない。

 このMicrocodeとは何か?といえば、内部命令セットである。例えばx86の場合、32bitに限っても加算(ADD)命令が15種類ある。例を挙げると、

  • (1)ADD EAX, imm32 EAXレジスタの内容に、imm32で示される値を加算してEAXレジスタに書き戻す
  • (2)ADD r/m32, imm32 r/m32で示されるアドレスorレジスタの内容に、imm32で示される値を加算して、元のr/m32で示されるアドレスorレジスタに書き戻す

といった具合だ。ここで(1)の場合は別に問題はないのだが、(2)で、特に1つ目の引数がメモリアドレスだと話が面倒である。つまり加算の前にメモリからのロード、加算の後にメモリへのセーブが必要になる。メモリへのセーブはまあExecuteの後のWritebeckにお任せするとして、加算の前のロードをADDに実装するのは手間がかかる。しかも実際にはADD以外にもたくさんの命令が、この「メモリの内容の直接参照」をサポートしているから、こうした命令全てにメモリロードの機能を実装していたら無駄が多すぎる。

 そこでMicrocodeの登場である。(1)であれば実行ユニットでは、単に加算をするだけだ。この場合マイクロコードはadd EAX+<値>→EAX EAXの値と<値>を足し、EAXに書き戻すという具合になる。一方(2)であるが、こちらは、

  • load m32→Reg m32で示されるアドレスの内容を作業レジスタRegにコピー
  • add Reg+<値>→Reg Regの値と<値>を加算してRegに書き戻し
  • save Reg→m32 Regの内容をm32で示されるアドレスに保存

といった形に分解して処理を行えば、実行ユニットの加算器はシンプルに加算をするだけで済むことになる。このうちsave Reg→m32は先も書いた通りWritebackにお任せなので、実行ユニットは1つのADD命令を、load+addという2命令に分解して処理を行う形にすれば、実行ユニットの構造をシンプルにできることになる。

 こうした実装は主要なCISCプロセッサではごく一般的である。もちろんこれを実装するにあたり、全ての命令をMicrocode実装にすると、Microcode ROMからの読出しの時間が長くなり、ここがボトルネックになりやすいということで、「簡単な命令はそのままデコード、複雑な命令はMicrocodeでデコード」という実装になることが多い。上の例で言えば、(1)はそのままデコーダー内部でadd EAX+<値>→EAXというフォーマットに変換して流すが、(2)のケースではMicrocode ROMを参照してload+addに変換して送り出す、という格好だ。

 ということで話がやっとPentium Proに戻ってきた。コールウェル氏の発想は、「どうせMicrocodeを使って内部命令に変換するなら、そこにRISC風の実装を行えば、RISCのメリットをそのままCISCに生かせる」というものである。

 デコード段までCISC、その後はRISCにすることで高い性能を得られるはず、というコールウェル氏の賭けは当たり、Pentium ProというかP6アーキテクチャは、その後拡張を重ねながら、20年以上もIntelで利用され続けている。

 実はこの頃、CISC命令をRISCに変換して処理、というアイデアは複数のメーカーが手掛けていた。例えばAMDは、Am29000にx86→29K(Am29000の略称)の変換部を組み合わせる形で、1996年にSSA/5(のちにAMD K5に改称)を投入する。

 当時AMDとIntelはMicrocodeの著作権を巡る訴訟合戦の最中であり、486やPentiumの設計情報やMicrocodeを利用できなかった。486はともかくPentiumに関しては全く歯が立たなかったAMDが窮余の策として放ったのが、Am29050というSuperScalar/Out-of-order構成のRISCプロセッサをx86互換に仕立て上げた訳だ。もっともこうした後付けで十分な性能が出たか、といわれると心もとないところで、Pentiumの初期の製品にはどうにかごする性能を出せたものの、続くPentium Proには敵わなかった程度であった。

 Pentium Proに先んじてCISC→RISC変換を実装したのが、NexGenというx86互換のファブレスメーカーが開発したNx586というプロセッサである。このNx586は1993年に発表、1994年に発売されたが、x86命令を独自のRISC86命令に変換、これをやはりPentium Pro同様にSuperScalar/Out-of-orderの実行部で処理するという方式を取っていた。

 パッケージがIntelのものとは非互換(独自のマザーボードが必要)であることや、FPUが別チップであるなどいくつか問題もあったため、広く成功するには至っていないが、それでも次のNX686というPentium Pro対抗製品を開発するには十分であり、こちらはPentium Proを上回る性能を引き出せると主張していた。

photo NexGenによる、x86命令を内部のRISC命令(ROPs)に変換する効率をNX686とPentium Proで比較したもの。NexGenの方がより効果的にRISC命令に変換を行っていると主張していた。出典はMicroprocessor Reportの1995年10月23日号

 ちなみにこのNx686は、その後NexGen自身をAMDが買収。外部I/FをPentium互換にした上で、AMD K6として1997年に発売された。

 その1997年には、IDTからWinChip C6という、これまた異なる互換x86プロセッサが発売されているが、実はこのWinChip C6も内部はRISCで、デコーダー部でx86をRISC風に分解して処理する形で実装されている。要するに1990年あたりから、一斉にCISCの実装方法が変わり始めた訳だ。実際この後もCISCのままの実装にこだわったのは唯一Cyrixくらいのもので、それもあって2000年のVIA Technologiesによる買収の後、真っ先に切り捨てられることになってしまった(WinChip C6を設計したCentaur Technologyがいまだに健在なのと、ある意味対照的である)。

Copyright © ITmedia, Inc. All Rights Reserved.