SMT(Simultaneous Multi-Threading)

演算レーテンシや1次キャッシュヒットのメモリアクセスのような数サイクルの空きサイクルを無駄にしない方法として、「同時マルチスレッディング(Simultaneous Multi-Threading:SMT)」という方式がある。スレッドごとにプログラムカウンタやレジスタのセットを持つのはVMTと同じであるが、SMTの場合は、命令ごとにどのスレッドの命令であるかという情報を持ち、この情報で使用するレジスタセットを選択する。

図1.5 SMTプロセサの構造

図1.5に示すように、スレッドごとのPCを持ち、フェッチユニットはスレッド1の命令、スレッド2の命令を交互に命令キャッシュから読み出し、それぞれの命令バッファに入れる。命令のフェッチは、命令バッファに空きがあれば次のキャッシュラインを読むというようにして、可能な限り命令バッファを埋めておくようにする。一方、命令バッファに空きが無ければ、そのスレッドの命令の読み出しは行わない。

なお、単純に次のキャッシュラインを読むという方法では、分岐命令がある場合はうまくいかないので、過去に実行したときの分岐先アドレスを記憶するBTB(Branch Target Buffer)などを使って次に必要となるキャッシュラインを予測するのが一般的である。

デコードユニットは、これらのスレッドごとの命令バッファから、一定の規則に従って命令を取り出す。2スレッドで特別な優先順位がない場合は、2つのスレッドから交互に命令を取り出す。

2つのスレッドは、一般的には関係の無い処理を実行しているので、異なるスレッドから取られた命令の間には依存関係は存在しない。従って、このように交互に2つのスレッドから命令を取り出すと、命令間のデータ依存関係による待ちサイクルの発生を減らすことができる。

デコードユニットは命令の種別、入力オペランドのレジスタ番号、結果オペランドのレジスタ番号を含む情報をレジスタファイル以降の実行パイプラインに送り出すが、SMTの場合にはこの情報を拡張して、レジスタ番号にその命令のスレッド番号を加える。

そして、複数のスレッドからの命令を混ぜて実行ユニットに送り込む。レジスタファイルは入力オペランドのスレッド番号で、どのレジスタセットを使うかを選択して、オペランドを読み出して演算をさせる。そして、結果格納オペランドのスレッド番号に従ってレジスタセットを選択して演算結果を格納する。このように、演算パイプラインの制御情報にスレッド番号を付け加えておけば、入力オペランドの読み込みステージにある命令はスレッド1、そのサイクルでの結果の格納はスレッド2の命令というケースでも問題なく処理できる。

SMTではVMTより若干多くの追加ハードウェアを必要とするが、その量はわずかであり、現状では、マルチスレッドという場合は、大部分はSMTとなっている。

なお、IntelのCoreプロセサやサーバ用のXeonプロセサで使われているマルチスレッドはSMT方式であるが、IntelのマーケティングはHyper Threadingと呼んでいる。