【図解】ハイパースレッディング(SMT)の仕組み~メリットとデメリット、悪影響や脆弱性などの問題について~

CPU コアとスレッドの関係

最近の CPU は、1つの CPU ソケットに複数のコア(実際に処理を行う部品)が付いています。

例えば Intel Xeon E5-2643V4 という CPU ではコア数は 6 です。

CPU コアとは実際に命令を行う部品のことで、ハイパースレッディング等のSMT(同時マルチスレッディング)登場以前においてはCPUコア数=同時に実行できる命令の数』でした。

実行中のプログラムは『プロセス』と呼ばれ、プロセスは 1 つ以上の『スレッド』を持ちます。このスレッドが CPU コアに命令を与えますので、

CPU コア数 = 同時実行できるスレッド数

でした。

先程の Intel Xeon E5-2643V4 は「コアの数 6」と書いてある下に「スレッド数 12」と書かれています。これは何でしょうか?

プロセスとスレッドの違い

プロセスとは、実行中のプログラムのことです。1 つのプロセスには、1 つのメモリ空間(メモリ領域)が割り当てられます。メモリ空間はプロセスから OS に要求すれば(空きがあれば)増やしてくれます。

スレッドとは、プロセス内で命令を逐次実行する部分であり、CPU コアを利用する単位のことです。前述の通り、SMT(同時マルチスレッディング)登場以前では 1 スレッドに 1 コアが基本でした。

ですが最近の CPU は、SMT (Intel ではハイパースレッディングと呼ぶ)機能を搭載しているモデルが多くなってきており、この機能を使うと、1 つのコアに対して複数のスレッド(多くは 2 つのスレッド)を割り当てることができます。

物理的に 1 つのコアを、OS からは 2 つのコアであるように見せかけることができコアの利用率を上げることができるのです。

なので、2 スレッドの SMT に対応している CPU であれば、「スレッド数」は「コアの数」の倍になります。

ハイパースレッディング(SMT)の仕組み

ハイパースレッディング(SMT)の登場前においても、1 つの CPU コアでの複数命令同時実行を実装した『スーパースカラ』というアーキテクチャがありました。

スーパースカラを採用した CPU では、1 つの物理コアに『実行ユニット(Execution Units)』という演算を実行する部品が複数あります。実行ユニットは「どういう順番でどのような演算を行うか」という一連の処理を定義した『パイプライン』を構成しています。

スーパースカラ CPU においては、OS から見た物理コアは 1 つだけなので、OS は並列処理については関知しません。1つのプロセス(実行中のプログラム)の命令を命令キャッシュからフェッチする際に、CPUコア自体が主体的に、依存性の無い命令を同時実行しようと試みます。(依存性がある命令を同時に実行すると期待と異なる結果になる可能性がある)

しかし 1 つのプロセス内で依存性の無い命令を探すことは難しく、実際の並列処理を行う割合は決して高くありませんでした。

この課題の解決策として出てきたのが『ハイパースレッディング』などの『SMT(同時マルチスレッディング)』です。

ハイパースレッディングを実装した CPU の例として Intel Skylake のマイクロアーキテクチャは以下のようになっています。

https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf

P.32 にある通り、Port 0/1/5/6 に接続されている 4 つの演算用実行ユニットがあることがわかります。複数の演算用実行ユニットを持つことによって同時に実行できる命令数を増やしているのです。

ですがこれだけではスーパースカラと変わりません。ハイパースレッディング対応の CPU で何が変わったかというと、OS から見た時に CPU コアを2つに見せるために、本来 1 つしか存在しない『Arch State』を 2 つ搭載した点です。

この Arch State とはプロセスの状態を保持するレジスタのことです。つまり、CPU 内のレジスタの一部が二重に存在するのです。

これによりプロセスの受け口が 2 つに拡張され、(スーパースカラのような1つのプロセス内ではなく)異なるプロセスのスレッドを同時実行できるようになるのです。OS やプロセスから見ると、コアがあたかも2つあるかのように見えるのです。

ハイパースレッディング(SMT)のモチベーションは、スーパースカラのときからの課題であった CPU コア内部の『実行ユニット(パイプライン)』の利用率を上げることです。1 つの物理コアが 2 つの論理コアに見えるのはこれを実装した結果であって、目的ではありません。(以前騒動になった Spectre/Meltdownの原因となった予測分岐やアウトオブオーダー実行も同じです。)

コア数が 2 倍になるからといって、効率が 2 倍になるわけではないのでその点は勘違いしてはいけません。

ハイパースレッディングのメリット・デメリット

メリット

異なるプロセスではお互いのスレッド(命令)への依存度はほぼ無いため、並列実行を行いやすいです。これによりパイプライン利用効率を高めることができます。

デメリット

実行ユニットはパイプラインの処理工程がそれぞれ異なっており、スレッドの命令の性質などに応じてどの実行ユニットが使われるかが決まります。

アプリケーションの組み合わせによっては、特定の実行ユニットの利用に偏りが生じ、同時実行できずに待ちが発生する可能性があります。

また、物理的な問題として、L1 ~ L3 キャッシュは物理コアで共有しているため、2 つのプロセスでキャッシュを共有します。そのため、片方のスレッドでキャッシュミスが多いと、もう片方のスレッドのキャッシュも追い出され、キャッシュミスが頻発してしまう、という悪影響を引き起こす可能性もあります。

なお、キャッシュを共有することにより、Spectre Variant 2 という脆弱性や
PortSmash (CVE-2018-5407)などが報告されており、今後もキャッシュ共有による影響は否定できません。

フォローする