ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

Hyper-V のルートスケジューラで他の VM の存在は仮想プロセッサのパフォーマンスにどれだけ影響するのか?

概要

Windows 10 の Hyper-V ではデフォルトのスケジューラが「ルートスケジューラ」となっています。このスケジューラは以下の説明がなされています。

ルート スケジューラの種類が有効になっている場合、ハイパーバイザーがルート パーティションに対する作業スケジュールの渡しを制御します。 ルート パーティションの OS インスタンスの NT スケジューラが、システム LP に対する実行スケジュール機能のすべての側面を管理します。

Hyper-V Hypervisor のさまざまな種類のスケジューラを理解して使用する | Microsoft Learn

Windows のスケジュールモデルについては以下の説明があります。

システムは、同じ優先順位を持つすべてのスレッドを等しいものとして扱います。 システムは、優先順位が最も高いすべてのスレッドにラウンドロビン方式でタイム スライスを割り当てます。 これらのスレッドのいずれも実行する準備ができていない場合、システムはラウンドロビン方式でタイム スライスを次に優先度の高いすべてのスレッドに割り当てます。 優先度の高いスレッドを実行できるようになると、システムは優先順位の低いスレッドの実行を停止し (タイム スライスの使用を終了せずに)、優先度の高いスレッドに完全なタイム スライスを割り当てます。

優先度のスケジュール設定 - Win32 apps | Microsoft Learn

この2つの説明を踏まえると、「ルートスケジューラ」について以下のことが想定されます。

  • ラウンドロビン方式のスケジュールモデルになる。
  • 仮想プロセッサ (VP) がなすべき仕事を持たなければ、タイムスライスの割り当てはない(オーバーヘッド分のみ)。

この想定が妥当であるかを検証しました。

検証環境

ホスト

プロセッサ Intel Core i5-6600 CPU @ 3.30GHz ※ 4 コアのCPUです
OS Windows 10 Pro バージョン 21H2
VM1
構成バージョン 9.2
プロセッサ 1 or 4 個の仮想プロセッサ
OS Red Hat Enterprise Linux release 8.7
VM2
構成バージョン 9.2
プロセッサ 4 個の仮想プロセッサ
OS Red Hat Enterprise Linux release 9.1

VM1 / VM2 で OS のバージョンは異なりますが、今回の検証には影響しないと想定しています。VM のスケジュールを管理するのはハイパーバイザーだからです。

検証

VM1 で sysbench を実行します。この sysbench の "events per second" でパフォーマンスへの影響を評価します。

-- 4 スレッドでの実行の場合
# sysbench --threads=4 --test=cpu run

VM 2 で stress-ng を実行します。これで他の VM による影響をシミュレーションします。

-- 3 CPU に 100% の負荷をかける場合
# stress-ng -c 3 -l 100

まず、VM1 だけを起動したときの測定結果を示します。ここでは VM1 の VP を 1 個にした時の結果も掲載します。

条件 パフォーマンス
1 VP - 1 スレッド 1271.76
4 VP - 1 スレッド 1271.18
4 VP - 4 スレッド 4682.52

VP の数による差異は微々たるものでした。

次に、VM2 を起動だけします(stress-ng を実行しない)。この時の VM1 での測定結果です。

条件 パフォーマンス
4 VP - 1 スレッド 1263.94
4 VP - 4 スレッド 4665.39

VM1 を単独起動したときと比べ、ほとんど差異はありませんでした。このことから、仕事のない VM に対してはタイムスライスが与えられないとわかります。

VM2 で 3 VP に対して 100% の負荷をかけます。この時の VM1 での測定結果です。

条件 パフォーマンス
4 VP - 1 スレッド 1152.60
4 VP - 4 スレッド 2627.75

1 スレッドの時は VM2 が何もしない時と比べ、パフォーマンスが若干低下した程度の結果となりました。物理 CPU が 4 コアなので、VM2 で 3 コア分占有されても、残りの 1 コアを利用可能だったためと思われます。

4 スレッドの時は VM2 が何もしない時と比べ、パフォーマンスが 56% 程度に低下しました。VM1 が 4 VP、VM2 が 3 VP フル稼働したと考えると、各 VM に与えられたタイムスライスの割合を以下のとおり推測できます。
物理コア数 / 稼働 VP 数 = 4 / (4 + 3) = 57%
これは低下したパフォーマンスの割合とほぼ同じです。

VM2 で 4 VP に対して 100% の負荷をかけます。この時の VM1 での測定結果です。

条件 パフォーマンス
4 VP - 1 スレッド 924.82
4 VP - 4 スレッド 2301.64

1 スレッドの時は VM2 が何もしない時と比べ、パフォーマンスが 73% 程度に低下しました。4 スレッドの時は VM2 が何もしない時と比べ、パフォーマンスが 49% 程度に低下しました。

先ほどと同様に各 VM に与えられたタイムスライスの割合を計算してみます。
VM1 が 1 スレッドの時:
物理コア数 / 稼働 VP 数 = 4 / (1 + 4) = 80%
VM1 が 4 スレッドの時:
物理コア数 / 稼働 VP 数 = 4 / (4 + 4) = 50%

VM1 が 1 スレッドの時の計算と実測に若干の差異が見られます。VM2 で 3 VP に対して 100% の負荷をかけた時にも 1 スレッドだとパフォーマンスが若干低下していたので、何かしらのオーバーヘッドがあったのかもしれません。

VM1 が 4 スレッドの時は計算と実測がほぼ一致しました。

まとめ

ルートスケジューラのスケジュールモデルに対する想定が妥当であることを確認できました。また、重みづけの設定をしなければ、タイムスライスは稼働している各 VP に対して均等に割り当てられることもわかりました。