同時マルチスレッディング(SMT)の原理 ─ 資源共有とスレッド競合
なぜ1コアが2スレッドを同時に捌けるのか。遊んでいた発行スロットを別スレッドで埋めるSMTの資源共有と、キャッシュ競合・サイドチャネルという代償を原理から掴めます。
- 1.SMTはアウトオブオーダコアの遊休発行スロットを複数スレッドの命令で埋め、フロントエンドと実行ユニットを同一サイクルで共有してスループットを上げる。
- 2.資源はROB/LSQ/物理レジスタの静的分割か動的共有で扱い、共有のしすぎは片スレッドの占有を招き、分割のしすぎは利得を削る。共有L1/L2の容量競合がワークロード次第で逆効果になる。
- 3.実行ユニット・キャッシュ・分岐予測器を兄弟スレッドと共有するため、占有状況がレイテンシ差として漏れ、L1TFやMDSのようなマイクロアーキテクチャ・サイドチャネルの温床になる。
なぜ実行ユニットが遊ぶのか
アウトオブオーダ実行を備えた現代のコアは、1サイクルに4〜8命令を発行できる広い実行幅を持ちます。ところが単一スレッドだけを流すと、その幅はめったに埋まりません。キャッシュミスで命令ウィンドウが依存待ちで詰まる、分岐予測ミスでパイプラインが空になる、長い依存鎖でオペランドが揃わない――こうした理由で、多くのサイクルで発行スロットの半分以上が空のまま捨てられます。
この遊休を「縦」と「横」に分けて埋める手法が、マルチスレッディングです。同時マルチスレッディング(SMT)は、複数のハードウェアスレッドの命令を同一サイクル内で同時に発行ユニットへ投入し、片方のスレッドが埋め切れない横方向のスロットを、もう片方の独立した命令で埋めます。IntelのHyper-Threadingがこの実装の代表で、物理1コアをOSから見て2つ(実装によっては4〜8)の論理プロセッサとして見せます。
| 方式 | 切り替え粒度 | 同一サイクルに混在 | 遊休の埋め方 |
|---|---|---|---|
| 粗粒度MT | ストール発生時 | 不可 | 長レイテンシ時だけ別スレッドへ |
| 細粒度MT | 毎サイクル | 不可 | 縦方向(サイクル単位で交代) |
| SMT | 毎サイクル | 可能 | 縦+横(空きスロットを別スレッドで充填) |
粗粒度・細粒度MTがサイクル単位でスレッドを交代させるだけなのに対し、SMTだけが同一サイクルの発行幅を複数スレッドで分け合えます。これが、アウトオブオーダの広い実行幅と本質的に相性が良い理由です。
フロントエンドの共有 ─ どこでスレッドを混ぜるか
SMTで最初に問題になるのは、各スレッドの「どこを実行中か」を別々に追うフロントエンドです。プログラムカウンタ、命令フェッチ列、リターンスタックなどはスレッドごとに複製(replicate)する必要があります。一方でフェッチ帯域やデコーダは高価なので共有します。
フェッチ段の典型: サイクルごとに片スレッドを選んでフェッチ
Thread0: ████ ____ ████ ____ ← ICacheミス中は譲る
Thread1: ____ ████ ____ ████
→ ラウンドロビンや「詰まり度の小さい方優先」で選択
フェッチ自体は1サイクル1スレッドでも、デコード後の命令はリネーム・発行段で混在します。リネーム段では論理レジスタ→物理レジスタの対応表をスレッドごとに持ちますが、割り当て先の物理レジスタファイルは共有プールから引きます。ここで早くもスレッド競合が始まります。片スレッドが多くの未確定命令(in-flight)を抱えると物理レジスタを食い尽くし、もう片方が発行できなくなります。
SMTの資源は性質ごとに扱いが分かれます。複製するのは状態を持つ最小限の構造(PC・アーキテクチャレジスタ像・リネームテーブル)。**分割(partition)**するのはキューのように静的に半分ずつ割り当てる方が公平な構造。**共有(share)**するのは実行ユニットやキャッシュのように本数を増やすと高価で、競合を許してでも稼働率を上げたい構造です。この三分類のどれを選ぶかが、SMT設計のほぼすべてです。
実行資源の分割と共有 ─ ROB・LSQ・レジスタ
順不同に並べ替えるための構造――リオーダバッファ(ROB)、ロード/ストアキュー(LSQ)、リザベーションステーション、物理レジスタ――は、SMTの利得と公平性を左右する核心です。代表的に2つの戦略があります。
| 資源 | 静的分割の例 | 動的共有の例 | トレードオフ |
|---|---|---|---|
| ROB | 各スレッドにエントリ数を半固定 | 空きを早い者勝ちで使用 | 分割は公平・共有は単一スレッド時に全幅使える |
| LSQ | スレッドごとに別領域 | 共通プールを競合使用 | メモリ順序の追跡をスレッド内で閉じやすいのは分割 |
| 物理レジスタ | ほぼ共有プール | リネームで奪い合い | 共有はピーク性能、片寄りで枯渇リスク |
Intelの初期Hyper-Threadingは、ROBやLSQのような順序を持つキューを静的に分割し、片スレッドの暴走が全体を止めない公平性を優先しました。半面、1スレッドしか走っていなくても半分しか使えず、シングルスレッド性能を犠牲にします。これを緩めるのが動的共有で、空きエントリを早い者勝ちで割り当てて稼働率を上げる代わりに、上限(しきい値)を設けて一方が占有し尽くすのを防ぎます。
共有資源には必ず「占有(resource hog)」のリスクが伴います。たとえば長いキャッシュミスを連発するスレッドは、解決待ちのロードでLSQやROBの先頭を塞ぎ、エントリを抱えたまま離しません。すると相方は発行できる命令があっても空きエントリが無く発行を止められます。これを避けるため、しきい値による上限設定や、詰まったスレッドのフェッチを絞るICOUNT(in-flight命令数の少ないスレッドを優先)などのフェッチ制御が使われます。
スループット利得とキャッシュ競合
SMTの利得は無条件ではありません。利得が大きいのは、各スレッドが単独では実行幅を埋め切れない――つまりメモリ待ちが多くILP(命令レベル並列性)の低いワークロードです。遊んでいたスロットを相方が埋めるので、合計スループットが伸びます。一般に2スレッドSMTの実効利得は**おおむね15〜30%**で、コアを2つ並べる(=2倍)には遠く及びません。同じ実行ユニット群を共有するだけだからです。
逆に利得が小さい、あるいは負になるのが、各スレッド単独で実行幅をほぼ埋めるワークロードです。SIMD/ベクトル演算で実行ユニットを飽和させるHPCカーネルなどでは、相方に渡す空きスロットがそもそも無く、得るものはありません。
さらに深刻なのがキャッシュ競合です。L1/L2はキャッシュの原理どおり容量が限られ、SMTでは2スレッドが同じL1を共有します。一方が大きな作業集合でキャッシュを掃き出すと、相方の有効容量が実質半減し、双方のミス率が上がります。これを**キャッシュ汚染(pollution)**と呼び、最悪では両スレッドのIPC(命令毎サイクル数)がSMT無効時を下回ります。SMTを有効にしてかえって遅くなる事例は、このL1/TLB容量とメモリ帯域の取り合いが原因です。
鍵は「単独でのコア稼働率」です。稼働率が低い(メモリバウンド・分岐予測ミスが多い・依存鎖が長い)ほど空きスロットが多く、SMTの充填効果が効きます。逆に稼働率が高い(演算密度が高くキャッシュに収まる)と、共有資源の取り合いだけが残ります。サーバー系のリクエスト処理は前者寄り、密行列演算は後者寄りです。プロファイルを取り、SMTオン/オフ両方で実測して判断するのが実務の定石です。
代償としてのサイドチャネル
資源共有は性能のためですが、その共有こそがセキュリティ上の弱点になります。兄弟スレッド(同一物理コアの論理プロセッサ)は実行ユニット・キャッシュ・分岐予測器・LSQを物理的に共有するため、一方の振る舞いが他方に観測可能な物理量として漏れます。
- ポート競合:相手が特定の実行ポートを使うと、自分の同種命令のレイテンシが延びる。この遅延差から相手の命令系列を推定できる(PortSmash型)。
- 共有キャッシュ:相手のアクセスで自分のラインが追い出され、再アクセスのヒット/ミス差から相手のアクセスパターンが漏れる。
- 共有キャッシュ経由の投機漏洩:L1Dに存在するデータが、フォルトするロードの投機実行で兄弟スレッドへ漏れる(L1TF/Foreshadow)。
- 共有バッファの残留データ:ストアバッファ・ラインフィルバッファ・ロードポートの残留データが、MDS(RIDL/Fallout/ZombieLoad)系の脆弱性で兄弟スレッドへ漏洩する。
L1TF系ではL1Dキャッシュに残るデータが、MDS系ではマイクロアーキテクチャ・バッファの残留データが、いずれも投機実行を通じて兄弟スレッドから読み出せます。マイクロコードやOSのバッファ消去で緩和できますが、信頼境界が異なるテナントを同一物理コアに同居させる構成(マルチテナントのクラウドなど)では、根本的な遮断のためSMT自体を無効化するのが確実な緩和策として推奨される場面があります。性能とセキュリティが正面から競合する、SMTの設計上のトレードオフが最も鋭く現れる箇所です。これは分岐予測器の共有が招く投機実行攻撃と地続きの問題です。
「SMTは同一サイクルに複数スレッドの命令を発行できる点が細粒度MTと異なる」「PC・リネームテーブルは複製、ROB/LSQは分割または動的共有、実行ユニット・キャッシュは共有」「利得は単独で実行幅を埋め切れないワークロードで大きく、キャッシュ競合で逆効果にもなる」「共有資源がサイドチャネルの源で、緩和のためSMT無効化が選ばれることがある」が頻出です。
まとめ
- SMTはアウトオブオーダコアの遊休発行スロットを、複数スレッドの独立命令で同一サイクルに充填し、実行ユニットの稼働率を上げる手法。
- 資源はPC・リネームテーブルを複製、ROB・LSQを静的分割か上限付き動的共有、物理レジスタ・実行ユニット・キャッシュを共有し、片スレッド占有を防ぐフェッチ制御(ICOUNTなど)で公平性を保つ。
- 利得は単独では実行幅を埋め切れないメモリバウンド系で大きい一方、L1/TLBのキャッシュ競合により逆効果になりうる。
- 共有資源はポート競合・キャッシュ・残留バッファ経由のサイドチャネルを生み、L1TF/MDS系では緩和のためSMT無効化が選ばれることがある。
CPU/メモリ/ディスク Article
同時マルチスレッディング(SMT)の原理 ─ 資源共有とスレッド競合を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
SMT
比較で見る軸
難易度: advanced / カテゴリ: CPU/メモリ/ディスク / タグ数: 5
導入後に効く点
資源はROB/LSQ/物理レジスタの静的分割か動的共有で扱い、共有のしすぎは片スレッドの占有を招き、分割のしすぎは利得を削る。共有L1/L2の容量競合がワークロード次第で逆効果になる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- CPU/メモリ/ディスク
- タグ数
- 5
判断チェックリスト
- 自社の用途が「SMT / Hyper-Threading」に近いか確認する。
- 強みである「SMTはアウトオブオーダコアの遊休発行スロットを複数スレッドの命令で埋め、フロントエンドと実行ユニットを同一サイクルで共有してスループットを上げる。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。