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 のマイクロアーキテクチャは以下のようになっています。
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 倍になるわけではないのでその点は勘違いしてはいけません。
Intel 公式では最高 30% となっています。
コアがほかのタスクが完了するのを待っているアイドルタイムを活用することで、インテル® ハイパースレッディング・テクノロジーは CPU スループットをサーバーアプリケーションで最高 30% 向上することが可能です。
ハイパースレッディングのメリット・デメリット
メリット
異なるプロセスではお互いのスレッド (命令) への依存度はほぼ無いため、並列実行を行いやすいです。これによりパイプライン利用効率を高めることができます。
デメリット
実行ユニットはパイプラインの処理工程がそれぞれ異なっており、スレッドの命令の性質などに応じてどの実行ユニットが使われるかが決まります。
アプリケーションの組み合わせによっては、特定の実行ユニットの利用に偏りが生じ、同時実行できずに待ちが発生する可能性があります。
また、物理的な問題として、L1 ~ L3 キャッシュは物理コアで共有しているため、2 つのプロセスでキャッシュを共有します。そのため、片方のスレッドでキャッシュミスが多いと、もう片方のスレッドのキャッシュも追い出され、キャッシュミスが頻発してしまう、という悪影響を引き起こす可能性もあります。
なお、キャッシュを共有することにより、Spectre Variant 2 という脆弱性や PortSmash (CVE-2018-5407)などが報告されており、今後もキャッシュ共有による影響は否定できません。
コメント
はじめまして、いつも勉強させていただいております。
HTT(SMT)について質問させていただきたくコメントさせていただきました。
個人の認識ではSMTというのはプログラムカウンタや各種レジスタ等がスレッド数分用意されており、そこから命令を送り出す。
それらの命令を交互に行い、キャッシュミスなどの原因で遅延が起こった場合、無事?な片方のスレッド処理を重点的に行うという認識で、同時マルチスレッドとはいうものの、完全に同時にでは無いという認識なのですがこの解釈は間違っておりますでしょうか?
駄文な文章で失礼いたしますが、ご教授頂けますと幸いです。
コメントありがとうございます!
ちょっと私の理解とは異なりますね。。いえ、私の理解がいい加減なのかもしれませんが、、もしかして『スイッチ・オン・イベント・マルチスレッディング』のことを仰っていませんか?
以下のPDFにそれっぽい記載があります。
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/vol6iss1_art01_j.pdf
—以下引用—
一方、スイッチ・オン・イベント・マルチスレッディングと呼ばれる方法では、キャッシュ・ミスなどレイテンシの大きいイベントが発生するとスレッドの切り替えを行います。このアプローチは、サーバ・アプリケーションのようにキャッシュ・ミスが大量に発生し、しかも2つのスレッドが類似したタスクを実行しているような場合には特に効果を発揮します
——
ご返信ありがとうございます!
リンク先の書類に目を通して改めて勉強してみます!
ありがとうございました!