
開発のために、1 つの Ubuntu Linux ホストで、異なる OS を搭載した多数の VirtualBox VM を使用しています。時々、スクリプトが間違って、VM CPU の 100% をロードし始めます。また、1 つの VM が CPU を 100% ロードすると、ホスト システムも使用できなくなります。遅いのです。
次に、トップを(非常にゆっくりと)開き、VirtualBox プロセスが CPU の 240% を使用していることを確認し、CPU をロードしている VM が見つかるまですべての VM ウィンドウを開いてプロセスを強制終了します。CPU を大量に使用している VirtualBox プロセス全体を強制終了したくはありません。
すべての VM は、1 つの CPU コアのみを使用するように構成され、実行キャップは 100% です。CPU は AMD FX 8370 (8 コア、16 スレッド) で、ホストはファイルシステムが正しく配置された SSD RAID 10 で実行されています。Windows ホスト環境ですか? もちろん違います! では、なぜ速度低下が発生するのでしょうか?
おそらく、すべての VirtualBox VM に最初のコアのみが割り当てられる (Windows が通常行うように) ためでしょうか? それを確認する方法と、各 VM が各コアを使用するようにする方法はありますか? 他にも推測できる点はありますか?
おそらくこの質問は、「Linux で特定のコアに任意のアプリを割り当てるにはどうすればよいか」ということだけでしょう。
答え1
あなたの質問に対する答えはありませんが、少なくともあなたの痛みを和らげることはできます。
各VMをコマンドラインから起動すると、例えば次のようにします。
VBoxManage startvm Name_of_VM --type headless
すると、オプション付きの top コマンドは、-c
プロセスを開始した完全なコマンドも表示します。この方法では、すぐに原因となっているプロセスを特定し、そのプロセス自体k
のオプションを使用して強制終了することができますtop
(特定した強制終了するプロセス番号を指定する必要があります)。
良い点はこれは、CLI からではなく GUI からすべての VM を起動した場合でも機能します。
編集:
よく考えてみると、おそらく私はあなたの質問の答えを知っているでしょう。これが本当にあなたが探しているものかどうかはわかりませんが、この場合は、そう教えてください。
プロセスの実行を事前に指定されたコアに制限するLinuxユーティリティはですtaskset
。これはデフォルトでインストールされているはずですが、インストールされていない場合はパッケージを確認してutil-linux
ください。プロセスを表示できます。親和性(つまり(実行が許可されているCPUのリスト)
taskset -cp Process_ID
(p
フラグは、後に続くのがプロセス番号であることを指定します。フラグc
は、文字列を CPU コアの 16 進表現に置き換えます。これがデフォルトになります)。
すでに実行中のプロセスをコア0と1でのみ実行するように割り当てることができます。たとえば、
taskset -cp 0,1 Process_ID
または、次の方法でコア 0 のみで新しいプログラムを起動します。
taskset -c 0 VBoxManage startvm Name_of_VM --type headless
2つの注意点があります。まず、プロセスを単一のCPUで実行するように制限したという事実は、それがそのCPUで実行される唯一のプロセスであることを意味するわけではありません。そのCPUを含むアフィニティを持つすべてのプロセスは、一定時間そのCPUで実行されます。 で設定したプロセス専用に特定のCPUを予約したい場合はtaskset
、isolcpus
指定されたCPUをカーネルスケジューラから分離するブートローダーの Linux カーネル コマンド ラインにパラメータ isolcpus=[cpu_number] を追加するだけです。
また、プロセスを単一の CPU に限定することは、total solution
あなたが考えているようなことではないことも知っておく必要があります。CPU はあらゆる種類の周辺機器を使用しますが、特定の状況下では、問題の周辺機器が使用できなくなり、CPU が要求をループし、バスとおそらく周辺機器も要求で過負荷になるため、CPU が停止することがあります。例を挙げましょう。私は Wine で実行している Sonos コントローラーを使用していますが、VPN を有効にすると、カリフォルニアの本拠地から切断され、ネットワーク要求がシステムに殺到し続けます。これは単一の CPU に限定することとはまったく関係ありません。
答え2
MariusMatutiae の回答のおかげで、起動されたすべての VirtualBox VM を異なるコアに分散する「スプレッダー」スクリプトをようやく作成できました。さらに、VMware VM でも同じことを行います。
このスクリプトを使用するには、すべての VM がシングルコアである必要があります (設定で設定できます)。それ以外の場合は、grep regexp を変更して除外できます。
#!/bin/bash
#getting possible affinity lists
AFFINITY=($(taskset -cp 1 | sed 's/.*\([0-9]\)\+[-]\([0-9]\+\).*/\1 \2/'))
echo Detected min_cpu: ${AFFINITY[0]}, max_cpu: ${AFFINITY[1]}.
CURRENT_AFFINITY=${AFFINITY[1]};
ps -Af | grep -i "[V]irtualBox.*comment\|.*[.]vm[x]" | awk -F" " '{ print $2}' |
# Iterating backwards because I think that farther cpus are less loaded. Maybe I am wrong
while read pid
do
echo Setting $pid to cpu $CURRENT_AFFINITY
taskset -cp $CURRENT_AFFINITY $pid
#loop stuff
let CURRENT_AFFINITY=CURRENT_AFFINITY-1;
if [[ "$CURRENT_AFFINITY" -lt ${AFFINITY[0]} ]];
then
CURRENT_AFFINITY=${AFFINITY[1]};
fi
done
VirutalBox VM でのみ動作させたい場合は、[V]irtualBox.*comment\|
grep パターンから削除します。VMware VM でのみ動作させたい場合は、\|.*[.]vm[x]
grep パターンから削除します。
このスクリプトを適用した直後、すべての VM で数秒間遅延が発生します。その後、すべてが正常になり、期待どおりに動作します。
今では、VM は過負荷になっても CPU を消費することはなく、Firefox は CPU を消費しても満足しています。しかし、それはまた別の話です... :/