簡単にわかるCPUの高速化技術

 たまたま立ち寄った小さな図書館にCPUの本があったんでぱらぱら読んだんですが、メモ


 えーと誰でもわかるぐらい簡単に高速化技術の変遷をまとめてみたいと思います

  • 486

 回路をワイヤードロジック化
 スーパーパイプライン

 スーパースカラ搭載

  • PentiumPro

 投機実行
 内部でRISC命令に置き換える

 MMX命令搭載

 SSE搭載
 アウトオブオーダー実行

 パイプラインの段数を倍化
 HT

  • Itanium

 64ビット化
 VLIW

 VLIW



たしかこんな感じだったかな(記憶なんであやふや)

  • スーパースカラってのは

演算回路、たとえば、足算、引き算、レジスタ格納とかの回路を同時に二つ実行できるようにするってことです。
 そもそも回路ですから並列動作はいくらでもできるわけで、
 命令に依存関係が無い場合は同時に動かしたほうが速くなるのは当然です。


 例をあげると、
 ご飯を食べて、TVを見て、風呂に入っている処理は、
 ご飯を食べならがらTVを見れば、2/3に処理が短縮されます。
 同時に風呂に入れば1/3になり、3倍に速くなります。

  • アウトオブオーダー

 直訳すると順番を守らないことです。
 上記のスーパースカラをさらに進めて、後から来た命令を(依存関係が無いなら)先にどんどん実行してしまいます。


 例をあげると、
 あずまんが大王で、ちよちゃんが飛び級をして高校生になってる状態です。
 別に智ちゃんが高校を卒業するのを待つ必要はありません(無依存)

  • スーパーパイプライン


 CPUは「命令の解読」「レジスタ読み込み」「演算」「結果を格納」
 と言った感じで、流れ作業で処理をしますが、
 この流れ作業を短く区切るほど、全体が速く処理できます。


 Intelはクロック周波数を上げるために、分割段数をどんどん増やしています。
 逆にAMDは段数を増やさない(クロックが上がらない)で回路技術で高速化をしている。

  • SSEとかMMXとか

 これは、特定の特殊処理に専用命令を用意するってだけです

  • 分岐予測

 これは面白いです。
 スーパーパイプラインを進めればクロック周波数は上がりますが、
 「分岐命令」で「分岐が発生した場合」は、
 すでに先まで読み込んでいていた処理が「すべて無駄になります」
 パイプラインが細かく分割されていれば、よりムダになる量が増えます。


A B C D E F G H
 A B C D E F G H
  A B C D E F G H


A〜Hで8段のスーパーパイプラインで、Dが分岐命令で、分岐が発生したとすると、
 Dを処理するときには、すでに次の命令はCまで処理が進んでいます。
 その次の命令もBまで進んでいます。
 これがいったんご破算になると「せっかくパイプラインを増やして高速化」しているのに、瞬間的に「停止したかのような速度低下をまねきます」
 これを解決するには、
 あらかじめ分岐がどうなるかを予測しておいて、
 より確率の高い方を「処理しておく」ことです。
 予想確率が50%なら、速度低下も50%低下します。

  • 投機的実行

 分岐予測をさらに改良したのが、投機的実行です。
 これは、分岐で、どちらになるか確実に予測はできないので、
 あらかじめて、両方の処理をしておきます。
 分岐が確定した時点で、片方を取り消せばいいわけです。
 これなら理論的に、分岐による遅延が発生しません。


 ただ、処理を取り消すには、レジスタを書換えていれば戻す必要があり、前の状態をすべて保存しておく必要があります。

 複数の同時に実行できる命令をあらかじめセットにしておいて並列実行する技術です。(研究所レベルで大昔からある技術です)
 スーパースカラーは、その場で並列実行できるか確認しながらやるのにくらべて、
 VLIWは「コンパイラですでに並列実行できるか判断しておきます」
 利点は、回路が単純になることです。
 Crusoeは、VLIWを採用することで、回路が単純になったおかげで、
 発熱を抑えています。
 そしてVLIWとして並列実行するための「並列化」をソフトウェアで行っています。
 ソフトなので速度が低下しますが、並列実行することで、全体でそこそこの速度を達成しています。


 Itaniumuは、VLIWの欠点をさらに改良しています。
 たとえば、8並列のVLIWのCPUのバイナリコードは、すでに8命令のセットで書かれているため、
 将来、16命令同時実行ができるCPUが登場しても、高速になりません。
 そこで、逆に16命令で並列実行できるとみなしたバイナリコードを作っておいて、
 実際のCPUが8命令しか実行できない場合は、8x2に別けて実行します。
 これで下位互換性が満たされます。
 (将来、CPUの並列度が上がれば、コードがそのままで速くなる)

  • HT

 ハイパースレッドですが、
 結局のところ、CPUは二個あるわけではないので、
 2個あるとみなせるようにしてハイパースレッドになって
 なぜ速くなるのかと考えると、
 スーパースカラのCPUなので、
 CPUは一つでも、演算回路レベルでは二並列で同時実行できると言えるわけで、(別に三でもいいです)
 別のタスクのスレッド同士は、「命令の依存関係がほぼ無い」とみなせるので、
 並列実行の依存関係の判断が簡単になる。


 おおまかに言って、AMDはパイプラインを深くしないのでクロック周波数は上がらないが、
 その分、分岐での速度低下の影響を受けにくくなる。
 クロックが低い分を、回路の工夫で、高速処理させる戦略と言えるようです。
 


 記憶と昔の知識に頼って書いてるので、あまりあてになりません(爆
 なんとなく大まかに解るんじゃないかなと。
 昨今のソフトウェアの複雑さと比べると、別に大したテクニックは使ってないように感じてしまいますね。個人的に(^^;)

 
 CPUの話って、クロックがどのくらいとか、キャッシュがどんくらいとか、
バス幅がどんくらいとか、そういう話しか最近は無いような気がしますが、
実際にどういう工夫をして動いているかはあまり知られて無いのではないでしょうか?
 自作ショップとかで「俺はハードに強い」という知り合いなんかに出くわしても、
 数値の話だけなんで、「それのどこがハードに強いのか?」と思ったりします。
 もっとも、ハードというなら、CMOSトランジスタの特性がとうとかってレベルのことかもしれません(^^;)