將 VirtualBox VM 分佈在核心上

將 VirtualBox VM 分佈在核心上

我在一台 Ubuntu Linux 主機上使用許多具有不同作業系統的 VirtualBox 虛擬機器進行開發。有時我的腳本會出錯並開始載入 100% 的 VM cpu。當一台虛擬機器加載 100% cpu 時,我甚至無法使用主機系統 - 速度很慢!

然後我必須打開頂部(非常慢),看到 VirtualBox 進程使用了 240% 的 CPU,然後打開每個 VM 窗口,直到找到載入 cpu 的 VM 並終止進程。我不想殺死整個使用大量CPU的VirtualBox進程。

我的所有虛擬機器都配置為僅使用一個 cpu 核心,執行上限為 100%。我的 CPU 是 AMD FX 8370(8 核,16 執行緒),我的主機在 SSD raid 10 上運行,檔案系統正確對齊。我是在windows主機環境下嗎?當然不是!那為什麼我會遇到速度變慢的情況呢?

也許是因為所有 VirtualBox VM 只分配第一個核心(就像 Windows 通常那樣)?如何檢查以及如何讓每個虛擬機器使用每個核心?也許還有其他一些猜測?

也許這個問題只是:如何將任何應用程式分配給 Linux 中的特定核心?

答案1

我無法回答你的問題,但至少我可以減輕你的痛苦。

如果您從命令列啟動每個虛擬機,例如

VBoxManage startvm Name_of_VM --type headless

那麼帶有該選項的 top 指令-c也會顯示啟動該進程的完整指令。這樣您就可以立即識別罪魁禍首進程,並使用其k內部的選項殺死它top(您必須提供您剛剛識別出的要殺死的進程的編號)。

好處是,即使您從 GUI 而不是從 CLI 啟動所有虛擬機,這仍然有效。

編輯:

再想想,也許我知道你問題的答案。我不確定這真的是您要尋找的東西,在這種情況下請告訴我。

將進程的執行限制在預先指定的核心的 Linux 實用程式是taskset.預設情況下您應該有它,如果沒有請檢查包util-linux。可以顯示進程親和力IE,允許運行的 cpu 列表)通過

      taskset -cp Process_ID

(此p標誌指定後面是進程號,該c標誌將字串替換為預設的 CPU 核心的十六進位表示形式)。

您可以指定一個已經運行的進程僅在核心 0 和 1 上運行,例如,透過

     taskset -cp 0,1 Process_ID

或僅透過以下方式在核心 0 上啟動新程式:

      taskset -c 0 VBoxManage startvm Name_of_VM --type headless

兩個警告:首先,您將進程限制為在單一CPU 上運行這一事實並不意味著它將是在該CPU 上運行的唯一進程:所有親和性包括該CPU 的進程都將在一段時間內在該CPU 上運行它。如果您想要保留給定的 CPU 供您使用設定的進程獨佔使用taskset,則必須使用該isolcpus參數將給定的 CPU 與核心調度程序隔離。只需將參數 isolcpus=[cpu_number] 新增至引導程式的 Linux 核心命令列即可。

另外,應該提醒您,將進程限制在單一 CPU 上並不需要像total solution您想像的那樣。 CPU 使用任何類型的周邊裝置,在給定的情況下,它們可能會被卡住,因為相關週邊裝置變得不可用,這會導致CPU 在其請求中循環,並且總線甚至週邊也會因請求而過載。一個例子?我使用在 Wine 下運行的 Sonos 控制器;當我啟動 VPN 時,它會與位於加州的總部斷開連接,並不斷向我的系統發送大量網路請求。這與限制單一 CPU 無關。

答案2

在 MariusMatutiae 的回答的幫助下,我終於成功編寫了「傳播器」腳本,將所有啟動的虛擬機器虛擬機器傳播到不同的核心。此外,它也對 VMware 虛擬機器執行相同的操作。

要使用此腳本,您的所有虛擬機器都應該是單核心的(可以在設定中設定)。否則,您可以透過修改 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 也無法吃掉我的 cpu,而 firefox 真的很樂意吃掉這一切。但這是另一個故事了......:/

相關內容