番長Blog担当と化している東京kです。こんにちは。
Webがメインの会社なのに、CPUの話題を書いているのはなぜ?という指摘をいただきましたが、今やっていることに近いことを書こうとすると、うっかりすると書いてはいけないことを書きそうなので、そこそこ忙しいときには、全く違う分野の話を書くようにしています。
というわけで、今回もCPUの話でも。
前回のHTTの話で、ちらっとスーパースカラに触れたけれど「スーパースカラって何よ?」という話題が来たので、せっかくなのでその話を。
先の記事で「スーパースカラでCPUが複数の命令を同時に実行できる」とちらっと触れましたが、そもそも、CPUにとって「1つの命令」って何か?というところからの話です。
CPUにおける命令の単位
例えば「(1+2)×(3+4)」という計算があるとき、「1+2」がCPUが1つの命令として実行できる計算です。そのため、プログラム言語は最終的に以下の様な順番の命令を生成してCPUに処理を依頼します。
- ★1+2を計算して3をメモリーに格納する
- ★3+4を計算して7をメモリーに格納する
- ■3×7を計算して21をメモリーに格納する
こんなふうに、CPUは計算を行います。今回は3ステップで計算できました。
スーパースカラとは
ここで、もし、足し算をするユニットが2つあれば、上記の手順1を実行中に手順2も実行できます。つまり、★印が付いた命令が同時実行でき、実際には全部で2ステップで計算ができることになり、実行時間が66%に削減されたことになります。これがスーパースカラです。
OoOとは
では「1+2」の計算結果と、別途「(3+4)×(5+6)」の計算結果を得たい場合場合、プログラム言語が以下の様に分解した場合どうでしょう?
- ★1+2を計算して3をメモリーに格納する
- ★3+4を計算して7をメモリーに格納する
- ■5+6を計算して11をメモリーに格納する
- ▲7×11を計算して77をメモリーに格納する
手順2は、手順1の結果を待たずに計算できるので、同時に実行できます。一方で手順4は手順3の結果を待たなければ計算ができないため別で実行されます。結果として3ステップで計算が終わることになります。
ここで登場するのがOoO(Out of Order)機能です。OoOは指示された順番を変更して実行するという機能です。今回は手順1を手順3まで遅らせてみましょう。
- ★3+4を計算して7をメモリーに格納する
- ★5+6を計算して11をメモリーに格納する
- ■1+2を計算して3をメモリーに格納する
- ■7×11を計算して77をメモリーに格納する
赤字の部分が移動した命令です。これにより、手順1&2の間で依存関係は無く、手順3と4の間でも依存関係が無いため、合計2ステップで処理が実行できるようになりました。
これが、CPUの内部で行われているOoO機能です。
このようにCPUの内部では様々な高速化技術が使われています。
ここに書いた技術はもう数十年前の過去の技術ではありますが、プログラムを書くときの参考になる場合もあるので、興味があると覚えておくと良いかも知れません。
(まぁ、HTTやスーパースカラとかは、マルチスレッドプログラムの参考になるといえばなるけど、そもそも今はマルチスレッドプログラムなら、CPUのこの辺の考えも入ったデザインパターンが数多くまとまっているので、デザインパターン本を読んだ方が良いかもしれないけどね。)