IBMのPOWER3プロセサ

このようにCDC 6600やHEPといったスパコンでの先駆的な業績があったのであるが、汎用的なプロセサでマルチスレッドが使われたのは、IBMの「POWER3」プロセサではないかと思われる。メモリアクセスがキャッシュをミスしてメインメモリをアクセスするとデータがプロセサに届くまでに長い時間が掛り、その間、プロセサコアは遊んでしまう。

これではハードウェアの利用効率が悪いので、キャッシュミスなどで長い時間プロセサが止まる場合には、別のプログラムを実行すれば良いという考えが出てきた。このように実行するプログラムを切り替える方式を垂直(Vertical Multi-Threading:VMT)という。

図1.3に示すように、時刻T1でのスレッド1のメモリアクセスがキャッシュミスをすると、スレッド1のメモリアクセスの完了を待たずに、スレッド2に切り替えて実行を行う。そして、時刻T2でスレッド1のアクセスしたデータはプロセサに届くが、スレッド1は実行可能状態になったということを記憶するだけで、スレッド2の実行を続ける。

図1.3 VMTはキャッシュミスなどの事象が発生すると、実行するスレッドを切り替える

この例ではスレッド2はキャッシュミスやI/O要求などの長い待ち時間を必要とする命令は実行せず、実行を継続するが、時刻T3で、与えられたタイムスライス(例えば10ms)を使い切る。この時点ではスレッド1のメモリアクセスは終わり、実行可能状態になっているので、スレッド1の実行に切り替わる。

図1.4に示すように、VMT方式では、切り替えて実行するスレッドに対応するプログラムカウンタ(PC1とPC2)やレジスタ(レジスタ1とレジスタ2)を設け、どのスレッドを実行するかを指示するレジスタの値に従って、どちらを使用するかを選択する。そして、実行スレッド番号レジスタは、キャッシュミスなどの事象の発生で、実行スレッド番号を切り替える。このような機構の追加が必要となるが、それ以外の主要な部分は単一スレッドを実行するプロセサと同じで良い。

スレッド番号でプログラムカウンタやレジスタを切り替えるという点ではCDC 6600のPPやTeraのHEPと同じであるが、これらのプロセサは10個とか50個とかの多数のスレッドをサイクルごとに切り替えて実行するが、VMTの場合は、2~3個のスレッドをキャッシュミスやスライスのタイムスアップなどの、より粗い粒度で切り替えて実行するという点が異なる。

図1.4 VMTプロセサの構造

VMTの場合、ユーザ状態だけで切り替えを行う場合は、PCと汎用レジスタ、ステータスレジスタなどのユーザ状態で使うアーキテクチャレジスタを追加すればよい。一方、スーパバイザ状態でも切り替えを行う場合は、特権レジスタを含むすべてのアーキテクチャレジスタを追加する必要がある。

この追加のレジスタと切り替え機構は、一般にプロセサハードウェアの数%程度であり、僅かのハードウェアの追加で済む。そして、キャッシュミス時のメモリアクセスの待ち時間やIOの動作完了待ち時間などを、他のスレッドを実行することで有効に使うことができるようになる。

ただし、パイプライン実行の場合は、キャッシュミスを起こした命令以降の命令はキャンセルし、切り替える先のスレッドの命令を新たにフェッチしてくる必要があり、分岐予測がミスした場合のようなロスが発生する。このため、データ依存で前の演算結果を待つというような数サイクル程度の待ちの場合は、切り替えのオーバヘッドが大きくて有効では無い。

ということで、垂直マルチスレッドプロセサはキャッシュミスやI/O要求などの数10サイクル以上の待ちが発生してしまう場合にスレッドを切り替える。

性能向上の観点では、単一スレッド実行のプロセサではムダになる長い待ち時間を別のスレッドを実行することで、プロセサの使用率、あるいは、全スレッド合計のスループット(単位時間に実行できる仕事量)がどれだけ増えるかが問題である。VMTは、ソフトウェアから見ると2つの命令列を並列に実行するマルチプロセサに見えるのであるが、POWER3プロセサの場合は、スループットの向上は10~20%程度であった。数%のハードウェアの追加で10~20%の性能向上は悪くないのであるが、完全な2コアに比べると性能が低いので、(本当のマルチプロセサを買えない)Poor man's multi-processor(貧乏人のマルチプロセサ)と陰口を叩かれた。