RISC
1970年代後半、IBMなどの研究で、実際に使用されているプログラムを解析したところ、複数の処理を一気に行う高機能な命令や、いわゆる直交性のある、命令とアドレッシングモードの組み合わせの大部分は実際のプログラムでは使われていないことが判明した。これは、プログラミング技法が、従来のバイナリコードを意識したアセンブリ言語の記述による低レベルのプログラミング形態から、高級言語で記述してコンパイラを使ってバイナリコードを得る形態に移り変わったことの副産物である。それまでに設計されたCPUの命令セットには、当初アセンブリ言語でプログラムを記述するうえで便利な命令が含まれ、やがてコンパイラでコード生成を行う前提で、高級言語の制御構文をそのまま実行できるように、複雑な機械語の命令も実装される様になった。だが、当時のコンパイラはCPUが持つ利点をあまり生かせていなかった。というのもコンパイラの開発は非常に高度な技術を要し、困難を伴うことだったからである。市場にはそれでもコンパイラが浸透していき、直交性の利点や、複雑な命令の利点は薄められていった。
もうひとつの発見は、複雑な処理を行う命令の所要時間と、単純な命令を組み合わせて同等の処理を行わせる場合の所要時間を比較したとき、しばしば前者が遅いということである。このパラドックスは、CPUの設計に許容される期間の制限から生じた。
そうすると、後続の命令を読み込んでいる一方で先行の命令をデコードすることが可能となり、そして、次のサイクルでは実行、デコード、命令読み込みの三つとなり、実質的に複数の命令が並行して処理されていることになる。個々の命令を見ると、処理の完了までに数サイクルかかっていて決して高速ではない(レイテンシは短縮しない)が、次の命令との関係を見れば順次命令が実行され、1サイクル毎に命令の実行が終了していくことになる(スループットは高い)。これにより高速なシステムができ、プロセッサ内の資源が効率的に利用される。
もうひとつの解決法は処理ユニットをプロセッサ内に複数装備し、複数の演算を同時に行うスーパースケーラプロセッサの概念である。連続して読み込んだ複数の命令を、複数の処理ユニットに同時に投入して並列処理を行う。ただし、ある命令を実行するためには前の命令の実行結果を用いる(依存性がある)場合がしばしばあり、常にこの方法で性能を向上できるとは限らない。
パイプラインを導入したりスーパースケーラ化する手法は、単純なRISCアーキテクチャの設計に、調停機能や複数のデータパス、パイプラインレジスタを追加して性能を向上させようというものである。CISCでは複雑な命令を実装して、これにより一挙に複数の処理を行うことで性能を高めようとするのと対照的である。チップの面積は有限なので、性能向上のための仕組みを追加するためには何かを削らなくてはならないが、基本的なRISCアーキテクチャのCPUは非常に単純で面積が小さく、追加機能を実装する面積を確保するうえで非常に好都合だった。
初期のプログラミング環境では、コンパイラは存在しなかった。プログラミングは機械語かアセンブリ言語で行われた。プログラミングをより簡単にするため、コンピュータの設計者はどんどん複雑な処理を行う命令を追加していった。それはつまり、現在ならば高度なプログラミング言語で関数(サブルーチン)レベルで実現されるべきものだった。当時の風潮としてコンパイラの設計よりもハードウェアの設計のほうが簡単であるという考えがあり、結果として複雑なことはハードウェアに担わせることとなった。
高度な命令の追加を必要とする別の要因としてメモリ空間に強い制約があったことが上げられる。メモリは非常に高価で、システムに用意できるメモリ空間が限られていたので、プログラム容量を縮小することが強く要請された。例えば、当時のシステムには数キロバイトしかメモリが搭載されていなかった。そのため、業界は高度で複雑な命令を必要としていたし、命令は可変長になっていて、ひとつの命令でいくつものことをこなし、また、ひとつの命令でデータの転送と演算を同時に行っていた。当時は命令デコードを単純化するよりも命令にいろいろな機能を組み込むことが優先された。
また、当時主流であった磁気コアメモリのアクセス速度は遅かった。そのため、情報の密度を高めアクセスする回数を減らすことで、アクセス速度の問題を軽減できる。
CPU内のレジスタ本数が少なかったのは以下のような理由からである。
レジスタの記憶セルは外部のメモリの記憶セルよりさらに高価だった。当時の集積回路のレベルでは、大きなレジスタセットはチップやボードのエリアの無駄遣いとしか思われなかった。
オペランドとして指定したレジスタをポインタとしてメモリアクセスに使用したり、レジスタ値にオフセットを加えて実効アドレスを得るモードを持つ。それより複雑なアドレッシングは、演算命令を組み合わせて実効アドレスを算出した結果をレジスタに入れて使用する。
ハードウェアがサポートするデータ型が少ない
例えば、CISCには文字列やビットストリングを扱う命令を備えたり、多項式とか複素数を扱うものもあった。そのような命令はRISCには見受けられない。なお、最新のアーキテクチャではSIMD命令向けに、複数の値をパックしたデータ形式もサポートする。
RISCはハーバード・アーキテクチャを実現したものとも言われる。概念的に命令コードのフローとデータのフローが分離されているからである。これによって、命令キャッシュとデータキャッシュへ同時にアクセスすることができ、性能向上に寄与する。
初期のRISCの設計には分岐遅延スロットの仕組みも備えられていた。これは分岐命令や条件分岐の直後の命令を指し、条件分岐で条件の成立の分岐するしないに関わらず、必ず実行される(逆に言えば分岐の効力が発揮されるのが遅れる)。これは、分岐命令の処理中もALUに仕事をさせて、分岐にかかるオーバーヘッドを隠蔽するための手法である。現在は、CPUの速度とメモリアクセスの差が広がり、またスーパースカラ構成をとる場合には遅延スロットに適切な個数が変わるなど、実装の影響を受けるために良くない仕組みと考えられていて、最近のRISCでは実装が避けられている。