スーパースカラとOoOをなんとなく理解する説明

番長Blog担当と化している東京kです。こんにちは。

Webがメインの会社なのに、CPUの話題を書いているのはなぜ?という指摘をいただきましたが、今やっていることに近いことを書こうとすると、うっかりすると書いてはいけないことを書きそうなので、そこそこ忙しいときには、全く違う分野の話を書くようにしています。

というわけで、今回もCPUの話でも。

前回のHTTの話で、ちらっとスーパースカラに触れたけれど「スーパースカラって何よ?」という話題が来たので、せっかくなのでその話を。

先の記事で「スーパースカラでCPUが複数の命令を同時に実行できる」とちらっと触れましたが、そもそも、CPUにとって「1つの命令」って何か?というところからの話です。

CPUにおける命令の単位

例えば「(1+2)×(3+4)」という計算があるとき、「1+2」がCPUが1つの命令として実行できる計算です。そのため、プログラム言語は最終的に以下の様な順番の命令を生成してCPUに処理を依頼します。

  1. ★1+2を計算して3をメモリーに格納する
  2. ★3+4を計算して7をメモリーに格納する
  3. ■3×7を計算して21をメモリーに格納する

こんなふうに、CPUは計算を行います。今回は3ステップで計算できました。

スーパースカラとは

ここで、もし、足し算をするユニットが2つあれば、上記の手順1を実行中に手順2も実行できます。つまり、★印が付いた命令が同時実行でき、実際には全部で2ステップで計算ができることになり、実行時間が66%に削減されたことになります。これがスーパースカラです。

OoOとは

では「1+2」の計算結果と、別途「(3+4)×(5+6)」の計算結果を得たい場合場合、プログラム言語が以下の様に分解した場合どうでしょう?

  1. ★1+2を計算して3をメモリーに格納する
  2. ★3+4を計算して7をメモリーに格納する
  3. ■5+6を計算して11をメモリーに格納する
  4. ▲7×11を計算して77をメモリーに格納する

手順2は、手順1の結果を待たずに計算できるので、同時に実行できます。一方で手順4は手順3の結果を待たなければ計算ができないため別で実行されます。結果として3ステップで計算が終わることになります。

ここで登場するのがOoO(Out of Order)機能です。OoOは指示された順番を変更して実行するという機能です。今回は手順1を手順3まで遅らせてみましょう。

  1. ★3+4を計算して7をメモリーに格納する
  2. ★5+6を計算して11をメモリーに格納する
  3. ■1+2を計算して3をメモリーに格納する
  4. ■7×11を計算して77をメモリーに格納する

赤字の部分が移動した命令です。これにより、手順1&2の間で依存関係は無く、手順3と4の間でも依存関係が無いため、合計2ステップで処理が実行できるようになりました。

これが、CPUの内部で行われているOoO機能です。

このようにCPUの内部では様々な高速化技術が使われています。
ここに書いた技術はもう数十年前の過去の技術ではありますが、プログラムを書くときの参考になる場合もあるので、興味があると覚えておくと良いかも知れません。
(まぁ、HTTやスーパースカラとかは、マルチスレッドプログラムの参考になるといえばなるけど、そもそも今はマルチスレッドプログラムなら、CPUのこの辺の考えも入ったデザインパターンが数多くまとまっているので、デザインパターン本を読んだ方が良いかもしれないけどね。)