将 VirtualBox VM 分布在各个核心上

将 VirtualBox VM 分布在各个核心上

我在一台 Ubuntu Linux 主机上使用多个带有不同操作系统的 VirtualBox VM 进行开发。有时我的脚本出错并开始加载 100% 的 VM CPU。当一台 VM 加载 100% 的 CPU 时,我甚至无法使用主机系统 - 它很慢!

然后我必须打开 top(非常慢),查看 VirtualBox 进程是否使用了 240% 的 CPU,然后打开每个 VM 窗口,直到找到占用大量 CPU 的 VM 并终止进程。我不想终止使用大量 CPU 的整个 VirtualBox 进程。

我的所有虚拟机都配置为仅使用一个 CPU 核心,执行上限为 100%。我的 CPU 是 AMD FX 8370(8 核,16 线程),我的主机在 SSD raid 10 上运行,文件系统正确对齐。我在 Windows 主机环境中吗?当然不是!那么为什么我会遇到速度变慢的情况?

可能是因为所有 VirtualBox VM 都只分配了第一个核心(就像 Windows 通常那样)?如何检查这一点以及如何让每个 VM 使用每个核心?也许还有其他猜测?

也许这个问题只是:如何在 Linux 中将任何应用程序分配给特定的核心?

答案1

我无法回答你的问题,但至少我可以减轻你的痛苦。

如果你从命令行启动每个虚拟机,例如

VBoxManage startvm Name_of_VM --type headless

然后带有选项的 top 命令-c还会显示启动该进程的完整命令。这样您就可以立即识别罪魁祸首进程,并使用其k内部的选项将其杀死top(您必须提供刚刚识别出的要杀死的进程的编号)。

好消息是,即使您从 GUI 而不是从 CLI 启动所有 VM,这也能起作用。

编辑:

再想想,也许我知道你的问题的答案。我不确定这是否真的是你正在寻找的,在这种情况下,请告诉我。

将进程的执行限制在预先指定的核心上的 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 的回答的帮助下,我终于成功编写了“扩展器”脚本,将所有启动的 VirtualBox VM 扩展到不同的核心。此外,它还对 VMware 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 模式中删除。

刚应用此脚本后,您会看到所有虚拟机都出现延迟,持续几秒钟。然后一切都恢复正常,并按预期运行。

现在,即使超载,虚拟机也不会占用我的 CPU,而 Firefox 也很乐意占用所有 CPU。但那是另一个故事…… :/

相关内容