05.スーパースカラーとHyperThreading

●スーパースカラーとは

 Pentium無印の頃から、CPUにスーパースカラー(Superscalar:スーパースケーラとも言う)という機構が組み込まれた。
 CPUの命令実行ユニットのうち、いくつかの演算ユニット(Pentiumでは整数演算に関わる部分を2つ)用意して、互いに無関係な処理を同時に実行してしまう仕組みだ。

 Pentiumは、命令を読み取った時、互いに参照先・格納先が無関係な整数演算命令を見つけると、その2命令を同時に実行する。(記憶が定かではないが整数演算2,浮動小数演算1が同時実行できたと思った。)

 具体的に見ると、機械語をよく見ると、希にこんなパターンが現れる。

 A+B→C …命令1
 D+E→F …命令2
 A+F→G …命令3

 命令1は、AとBを足した結果をCに設定しなさいという命令、命令2は同様にDとEを足した結果を結果をFに設定しなさいという命令である。

 注目したいのは、命令1と命令2は、互いに無関係な演算だという点だ。無関係なので、同時に実行しても構わない。

 このような命令があると、2つの演算ユニットに命令1,命令2をそれぞれ割り振って同時に2命令分の演算を実行する。これがスーパースカラーの仕組みである。
 命令3については、直前の命令による演算結果が出ないことには実行できないため、これは単独で実行される。


2006/01/10
●Pentiumコード

 さきほどの例題の命令の配置を少々変えてみた。

 D+E→F …命令2
 A+F→G …命令3
 A+B→C …命令1

 上から順に実行しても最終的に出てくる結果は同じだが、「命令3は直前の命令の結果が求まっていないと実行できない」という制約によって、この命令の配列ではPentiumのスーパースカラーはうまく動作しない。
 そこで、同じ結果になるなら、さきほどの例題のような配列になるよう、コンパイラのオプティマイザ(最適化ルーチン)が命令の配置を変える。
 これがコンパイラに搭載されている「Pentiumコード」と呼ばれる最適化指定である。
 Pentum専用命令を使う訳ではない。
 同じ結果になるように命令の配列を変えただけなので、もちろん、従来のCPUでも問題なく実行できる。

 スーパースカラーでは、命令配置に気をつけなければならない。
 ただ、これはコンパイラがやることであって、ソースプログラムレベルでは気にする必要はない。


2006/01/08
●スーパースカラーの利点

 パソコンのCPUにもスーパースカラーが搭載され、何の工夫もしなくても従来のプログラムは(部分的にだが)並列実行するようになった。

 「あっけなく並列処理が実現したなぁ」というのが素直な感想だった。

 もちろん、同時実行を効率的に行うための命令配列にするよう、コンパイラ側を工夫する必要があるが、ソースプログラムレベルでは気にしなくても良い。

 プログラマの立場で言えば、基本的にプログラムに手を加えなくて良いという点がポイントが高い。効率的な動作のためには再コンパイルの必要があるが、並列演算を理想的に実現できる。


2006/01/10
●スーパースカラーも甘くない

 しかし、現実は甘くなかった。

 機械語命令を先読みして、並列に実行できる命令を積極的に同時実行するのがスーパースカラーだが、最新のPentium4でさえも3段止まりだそうだ。

 スーパースカラーは、複数の演算ユニットで命令を同時実行することで単位時間あたりの実行命令数を稼ぐのが目的である。そのために先行して行われる「互いの命令の間に因果関係がないかどうかをチェックした上で、実行ユニットを振り分ける処理」は、命令実行よりも何倍も速く実行されなければならない。

 命令の実際の内容(たとえば、2つの数を足す、0かどうかを調べるといった処理)よりも何倍も複雑な処理になるのは想像に難くない。スーパースカラー段数が増えるほど判定の複雑さが指数的に増えていく。
 
 しかも、ちょっと考えればわかることだが、互いに無関係な命令が延々並ぶ可能性はほとんどない。(どちらかと言うと、Aについて加減乗除を行って、もしAがゼロだったらBについて加減乗除を行って…というような局所的な操作が多く、複数の命令を同時に実行できる確率はそれほど多くない。)

 よって、スーパースカラー段数は多くても3段あたりが限度らしく、むやみに段数を増やしても速くなる可能性はほとんどないのだそうだ。


2006/01/08
●蓋を開けると

 Pentium4は、同時にパイプラインという仕組み(演算処理を小分けして、ベルトコンベア式に、実行する方式。それぞれの処理は単純なので、クロックを上げやすい)も組み入れて演算ユニットを複数追加していった。
 気が付くと、なんと用意されている演算ユニットのうち実質的に3割しか稼働していないという事が明らかになった。

 用意されているユニットをほぼフル稼働するような命令配置にすれば、100%の性能を発揮できるのだが、実際に「やりたいこと」の命令を並べると「整数演算ばかり」あるいは「浮動小数点演算ばかり」という偏りが出てしまい、せっかくのCPUパワーを100%引き出せていないのだそうだ。


2006/01/10
●HyperThreadingの登場

 そこで、Intelは、余った演算ユニット資源を有効活用するために1つのCPUでデュアルCPUのようにふるまうHyper-Threading(HT)を搭載した。

 HTの仕組みの詳しい話はIntelのサイトに譲るが、「機械語命令レベルの局所的な並列性についてはスーパースカラーでなんとかしたから、そこから先の並列処理(スレッドレベルの並列処理)はプログラマに任せた」という格好である。


2006/01/10
●HTで一番迷惑する人

 HTのための回路はCPU全体の5%程度しかないそうで、チップ面積自体、従来品とほとんど変わらない。(実は結構前から回路は搭載されていて、単に「無効」にしていただけという噂もある。)
 このため、製造コストはほとんど変わらない。

 CPUメーカーは(というかIntelは)HTによってCPUに付加価値を付けられるし、実際パフォーマンスを上げることが可能だ。

 エンドユーザーはほぼ1CPU分の値段で(仮想的なものとは言え)デュアルプロセッサを手に入れられる。

 願ったりかなったりの構図に見えるが、困るのはプログラマである。

 実質的なデュアルプロセッサであるHTを提供するIntelと、実質的なデュアルプロセッサのパフォーマンスアップを期待して買ったユーザーの間に挟まれて、リスクの大きなマルチスレッドをやらざるを得なくなったからだ。


2006/01/08

[戻る]