キャッシュミスが発生し、メインメモリからのデータの到着まで処理が止まってしまうことが判明した場合には、そのスレッドの実行を中断し、他の実行待ちのスレッドの切り替えるというマルチスレッドプロセサがある。このような切り替え方式をVertical Multi-threadと呼ぶ。なお、キャッシュミス以外にもTLBミスなどの長時間の待ちが見込まれる場合、あるいは、それぞれのスレッドに与えられたタイムスライスを使い切った場合にもスレッドの切り替えが行われる。

図10.4 Vertical Multithread方式のブロックダイヤ(上)と命令列

図10.4に示すように、Vertical Multithread方式のハードウェアは、命令をフェッチするアドレスを指すPC(Program Counter)をスレッドごとに持ち、実行中のスレッドの命令を連続して読み出す。そして切り替え事象が発生すると、別のPCに切り替え、そちらの命令を連続して読み出すという動作をおこなう。

そして、命令実行パイプラインは、スレッドの切り替えに時間が掛かっては意味がないので、スレッドごとにアーキテクチャレジスタを持っており、スレッドの切り替えに応じて使用するレジスタセットを切り替える。

このように、Vertical Multithreadを行うのに必要な追加ハードウェアは、PCとレジスタセットと切り替え機構程度であり、これらに必要なハードウェアはプロセサ全体からみると僅かであり、少ない負担で平均的なサイクルあたりの実行命令数を増加させることができる。

これに対して、複数のスレッドの命令をごちゃごちゃに混ぜて実行パイプラインに投入するマルチスレッド方式がある。このタイプのマルチスレッドをSimultaneous Multi-thread(SMT)と呼ぶ。

図10.5 Simultaneous Multithread方式のブロックダイヤと命令列

図10.5に示すように、SMTの場合は、スレッドごとに命令フェッチユニットを持ち、それぞれ担当するスレッドの命令を読み出す。ただし、実際のハードウェアとして複数のフェッチユニットを持つとは限らず、1つのフェッチユニットでサイクルごとに命令を読み出すスレッドを切り換えて、実質上、並列に命令を読むというような実装が一般的である。そして、それらの複数のスレッドの命令は混合されて命令実行パイプラインに送り込まれる。

一般には、各スレッドは対等であり、図10.5に見られるように、2つのスレッドの場合は、両者の命令が交互に実行パイプラインに送られる。そして、スレッド1がキャッシュミスなどの命令実行がストールする状態になると、実行可能なスレッド0の命令だけを実行パイプラインに送ると言う動作を行う。

パイプライン実行やスーパスカラ実行の場合、データ依存性や制御依存性によりハザードが発生することを述べたが、当然のことながら、無関係の処理を行っている異なるスレッドの命令間ではデータ依存性も制御依存性も存在しない。したがって、このように複数のスレッドからの命令を混合すると、命令あたりのハザードの発生頻度が減少し、実行パイプラインの利用効率を高めることができる。また、キャッシュミスなどが発生した場合にはそのスレッドの命令発行は止まるので、VMTと同等な効果も得られる。

このSMTプロセサでは、アーキテクチャレジスタをスレッド分用意する必要があるのに加えて、命令発行に際して、その命令がどのスレッドのものであるかを示す情報を命令に付加する必要がある。そして実行ユニットはオペランドの読み出し時点では、スレッド番号でレジスタセットを選択して読み出しを行い、演算結果の書き込み時点では、コミットリングに書き込まれた命令のスレッド番号を使って、書き込むレジスタセットを選択する。

リオーダバッファを用いてOut-of-Order実行を行うプロセサでは、このリオーダバッファは、マルチスレッド化によってエントリ数を増やすことが必要になるが、1つのリオーダバッファをすべてのスレッドで共有することができ、スレッドごとにリオーダバッファ設ける必要はない。一方、大きなレジスタファイルを持ち、リネーミングを行うアーキテクチャのプロセサでは、スレッドごとに大きなレジスタファイルを持つ必要があるが、それぞれのスレッドで必要なアーキテクチャレジスタ以外の追加のレジスタ数は単一のリオーダバッファの数よりは少なくて済む。スレッドごとに物理レジスタを持つ方式のプロセサの方が、多少、マルチスレッド化のオーバヘッドが大きいものの、この差は決定的というほど大きくは無く、どちらのリネーミングの方式でもSMT化したプロセサが作られている。