仮想化環境の CPU 構成を検討していると、「HT を有効にする」「HT を無効にする」という表現が出てきます。しかし、この言葉は物理ホストに対して使う場合と、仮想マシンに対して使う場合とで意味が異なります。物理ホストで HT を無効にすることは、物理 CPU が持つ SMT 機能をホスト側で使わないという話です。一方、VM 側で「HT を無効にする」と呼ばれがちな操作は、物理 CPU の HT 機能を無効化することではありません。
VM 側で実際に変えているのは、ゲスト OS へ提示する仮想 CPU トポロジーです。たとえば同じ 8 vCPU でも、1 ソケット、4 コア、2 スレッドとして見せるのか、1 ソケット、8 コア、1 スレッドとして見せるのかを変えられます。この違いを混同すると、物理コア、論理 CPU、vCPU、CPU ピニングの関係が崩れて見えます。この記事では、物理ホストの HT、VM の仮想 CPU トポロジー、実際の vCPU 配置を分けて整理します。
HT と SMT を分けて考える
HT は Intel の Hyper-Threading Technology の略称です。より一般的には、1 つの物理コアが複数のハードウェアスレッドを持つ SMT の一種として捉えられます。Linux Kernel の x86 topology ドキュメントでは、core は 1 つ以上の thread を持ち、thread は 1 つのスケジューリング単位、つまり論理 CPU に相当するものとして説明されています。
| 物理構成 | OS から見える構成 | 意味 |
|---|---|---|
| 24 物理コア、1 コアあたり 2 スレッド | 48 論理 CPU | 物理コアは 24 個のまま、スケジューリング単位が 48 個見える |
| 24 物理コア、1 コアあたり 1 スレッド | 24 論理 CPU | SMT を使わず、各物理コアを 1 つの論理 CPU として扱う |
ここで重要なのは、論理 CPU が 48 個見えていても、物理コアが 48 個あるわけではないことです。同じ物理コアに属する 2 つの論理 CPU は、CPU 内部の実行資源を完全に独立して持っているわけではありません。Linux では、同一コアに属する論理 CPU の関係を CPU topology の sysfs 情報から確認できます。
物理ホストで HT を無効にする
物理ホストで HT を無効にする場合、変更されるのは物理 CPU の機能と、ハイパーバイザーから見える論理 CPU 数です。24 物理コアのホストで 1 コアあたり 2 スレッドを使っていたなら、HT 無効化によってハイパーバイザーが実行先として扱える論理 CPU は 48 から 24 へ減ります。これは単なる表示上の変更ではなく、ホスト全体の CPU 資源に対する変更です。
| 状態 | 物理コア | 1 コアあたりのスレッド | ハイパーバイザーから見える論理 CPU |
|---|---|---|---|
| HT 有効 | 24 | 2 | 48 |
| HT 無効 | 24 | 1 | 24 |
この変更は、すべての VM に間接的な影響を与えます。ハイパーバイザーが使える実行先が減るため、オーバーコミット、CPU スケジューリング、VM 配置、性能設計の前提が変わります。セキュリティー要件や予測可能性を理由に SMT を使わない設計はあり得ますが、その場合はホスト全体の収容能力が変わるものとして扱う必要があります。
VM には vCPU と仮想 CPU トポロジーを提示する
仮想マシンには、物理コアをそのまま渡すのではなく、通常は vCPU を割り当てます。ゲスト OS からは複数の CPU が存在するように見えますが、その vCPU をどのようなソケット、コア、スレッドの組み合わせとして見せるかは、仮想 CPU トポロジーの設定で変わります。
| 仮想 CPU トポロジー | 合計 vCPU | ゲスト OS からの見え方 |
|---|---|---|
| 1 ソケット × 4 コア × 2 スレッド | 8 vCPU | 1 コアあたり 2 スレッドを持つ CPU 構成に見える |
| 1 ソケット × 8 コア × 1 スレッド | 8 vCPU | 各コアが 1 スレッドだけを持つ CPU 構成に見える |
libvirt では、仮想 CPU の topology 要素で sockets、cores、threads を指定できます。QEMU の -smp でも、sockets、cores、threads などのトポロジー要素を指定できます。どちらも、ゲストへ提示する CPU の構造を定義するための仕組みであり、物理ホストの HT 機能そのものを切り替える設定ではありません。
VM で HT を無効にするという表現は正確ではない
VM について「HT を無効にする」と表現する場合、実際には物理 CPU の HT を無効にしているわけではありません。変えているのは、ゲスト OS へ提示する仮想 CPU トポロジーです。たとえば、4 仮想コア × 2 仮想スレッドの 8 vCPU 構成を、8 仮想コア × 1 仮想スレッドの 8 vCPU 構成として見せ直す操作です。
| 表現 | 実際に変わるもの | 変わらないもの |
|---|---|---|
| 物理ホストで HT を無効にする | 物理 CPU の SMT 利用、ホストの論理 CPU 数 | 物理コア数 |
| VM を 1 コア 1 スレッドにする | ゲスト OS へ見せる仮想 CPU トポロジー | 物理ホストの HT 機能、ホスト側の論理 CPU 数 |
したがって、VM 側の操作は「仮想マシンの HT を無効にする」ではなく、「VM の仮想 CPU トポロジーを 1 コアあたり 1 スレッドにする」と表現した方が正確です。この言い換えは細かい言葉の問題ではありません。どの階層の設定を変更しているのかを明確にしないと、性能、収容、ライセンス、セキュリティーの議論が同じ場所に混ざってしまいます。
ホストが HT 有効なら VM も合わせるべきか
物理ホストで HT が有効な場合、VM にも 1 コアあたり複数スレッドの仮想 CPU トポロジーを提示することは、基本的には自然です。物理ホスト上では同一コアの兄弟スレッドが実行資源を共有しているため、ゲスト OS にもその関係を伝えた方が、CPU の見え方としては実体に近くなります。
| ホスト側の例 | VM 側の提示例 | 意図 |
|---|---|---|
| 物理コア 0 に論理 CPU 0 と論理 CPU 1 がある | 仮想コア 0 に vCPU 0 と vCPU 1 を見せる | 兄弟スレッドの関係をゲスト OS へ伝える |
| 物理コア 1 に論理 CPU 2 と論理 CPU 3 がある | 仮想コア 1 に vCPU 2 と vCPU 3 を見せる | 物理構造に近い仮想トポロジーを提示する |
反対に、物理的には兄弟スレッドを使っているのに、VM へは 4 コア × 1 スレッドとして提示すると、ゲスト OS からは 4 つの独立したコアに見えます。実際の共有関係とゲスト OS からの見え方がずれるため、CPU 使用率の解釈やスケジューリング上の期待がずれます。
仮想トポロジーだけでは物理配置を保証しない
ただし、仮想 CPU トポロジーを設定しただけで、vCPU が物理ホスト上の特定の兄弟スレッドへ配置されるとは限りません。仮想 CPU トポロジーは、ゲスト OS へ見せる CPU の構造です。一方、各 vCPU をホスト上のどの論理 CPU で実行するかは、ハイパーバイザー側の CPU スケジューリングによって決まります。
| 設計対象 | 決める内容 | 代表的な設定 |
|---|---|---|
| 仮想 CPU トポロジー | ゲスト OS へソケット、コア、スレッドをどう見せるか | libvirt の topology、QEMU の -smp |
| vCPU の物理配置 | 各 vCPU をホスト上のどの論理 CPU で実行するか | CPU ピニング、NUMA pinning |
通常の共有型仮想化環境では、vCPU が複数の論理 CPU 上を移動しながら実行されることがあります。この場合、VM には 2 コア × 2 スレッドとして見せていても、その仮想スレッドが常に対応する物理コアの兄弟スレッド上で動いているとは限りません。見せ方と配置は別の設定です。
CPU ピニングを行う場合
物理ホストと VM の CPU トポロジーを厳密に対応させたい場合は、仮想 CPU トポロジーの設定に加えて、CPU ピニングなどの配置制御が必要です。libvirt の vcpupin は、各 vCPU をホスト上の特定の CPU へ対応付けるための設定です。
| vCPU | VM 側の見え方 | ホスト側の配置例 |
|---|---|---|
| vCPU 0 | 仮想コア 0 のスレッド 0 | 論理 CPU 0 |
| vCPU 1 | 仮想コア 0 のスレッド 1 | 論理 CPU 1 |
| vCPU 2 | 仮想コア 1 のスレッド 0 | 論理 CPU 2 |
| vCPU 3 | 仮想コア 1 のスレッド 1 | 論理 CPU 3 |
このように設計すれば、VM に提示した兄弟スレッドの関係と、物理ホスト上の兄弟スレッドの関係を対応させられます。ただし、CPU ピニングは常に正解ではありません。一般的な業務 VM では、ハイパーバイザーの CPU スケジューラーに任せた方が、ホスト全体の CPU 資源を効率的に使える場合があります。
一方、低遅延処理、リアルタイム処理、パケット処理、性能の予測可能性が重要なシステムでは、CPU ピニング、兄弟スレッドの配置、NUMA ノード、メモリー配置まで含めて設計する必要があります。この場合に重要なのは、HT を有効にするか無効にするかという単語ではなく、どの vCPU がどの物理資源を共有しているかを説明できることです。
どの階層の HT なのかを明確にする
仮想化環境で HT について話す場合、少なくとも三つの階層を分ける必要があります。第一に、物理ホストに何個の物理コアがあり、SMT を使うことで何個の論理 CPU が見えているのか。第二に、VM に何個の vCPU を割り当て、どのような仮想 CPU トポロジーとして提示しているのか。第三に、その vCPU をホスト上のどの論理 CPU へ配置しているのか、または配置をハイパーバイザーに任せているのかです。
| 確認する階層 | 確認する問い |
|---|---|
| 物理ホスト | 物理コア数、SMT の有無、ホストから見える論理 CPU 数は何か |
| VM の仮想トポロジー | ゲスト OS へ何ソケット、何コア、何スレッドとして見せているか |
| vCPU の配置 | CPU ピニングや NUMA pinning で物理配置を固定しているか |
この三つを分けるだけで、「HT 無効化」という曖昧な言葉に引きずられにくくなります。物理ホストの HT 無効化は、ホスト全体の CPU 資源を変える操作です。VM の 1 コア 1 スレッド設定は、ゲスト OS へ提示する見え方を変える操作です。CPU ピニングは、vCPU の実行場所を制御する操作です。
まとめ
物理ホストにおける HT 無効化と、VM の仮想 CPU トポロジーを 1 コア 1 スレッドに設定することは、別の階層の操作です。物理ホストで HT を無効にすると、物理 CPU の SMT 利用が止まり、ハイパーバイザーから見える論理 CPU 数が減ります。一方、VM 側で 1 コア 1 スレッドにしても、物理ホストの HT 機能やホスト側の論理 CPU 数は変わりません。
また、仮想 CPU トポロジーを物理構造に似せたとしても、それだけで vCPU の物理配置は保証されません。見せ方を決める設定と、実際の配置を決める設定は分けて考える必要があります。仮想化環境の CPU 構成を設計するときは、物理コア、論理 CPU、vCPU、仮想 CPU トポロジー、CPU ピニングを同じ言葉で丸めず、それぞれの階層で何を変更しているのかを確認することが重要です。
参考書籍
書籍
作って理解する仮想化技術
KVM、QEMU、ハイパーバイザー、仮想デバイスなどを低いレイヤーから確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
参考資料
- libvirt: Domain XML format
- QEMU Documentation: Invocation
- Linux Kernel Documentation: x86 Topology
- Linux Kernel Documentation: How CPU topology info is exported via sysfs

