Поширення віртуальних машин VirtualBox над ядрами


2

Я використовую багато віртуальних машин VirtualBox з різними ОС на одному хості Ubuntu Linux для розробки. Іноді мої скрипти стають помилковими і починають завантажувати 100% процесора VM. І коли один ВМ завантажує 100% процесора, я не можу навіть використовувати хост-систему - це повільно!

Тоді я повинен відкрити верхню (дуже повільно), побачити, що процес VirtualBox використовує 240% процесора, а потім відкрити кожен вікно віртуальної машини, поки я не знайду VM, що завантажує процесор і вбити процес. Я не хочу вбивати весь процес VirtualBox, який використовує багато процесора.

Усі мої віртуальні машини налаштовані на використання лише одного ядра процесора, при цьому копіювання виконується на 100%. Мій процесор AMD FX 8370 (8 ядер, 16 потоків), мій хост працює на рейді SSD 10 з файловими системами. Я в середовищі Windows хост? Звичайно, ні! Чому ж я відчуваю уповільнення?

Може бути, тому що всі VirtualBox VM отримати тільки перший призначений ядро ​​(як вікна зазвичай роблять)? Як перевірити це і як зробити кожну віртуальну машину кожним ядром? Може бути, деякі інші здогадки?

Може бути, це питання просто: Як призначити будь-який додаток для конкретного ядра в Linux?


Чому ви не надаєте VM більше 1 CPU в налаштуваннях? Мені здається, що це звільняє і однорангові процесори
h0ch5tr4355

@ h0ch5tr4355 Я думав, що якщо я дам йому всі ядра, він буде завантажувати всі ядра замість одного ядра ....
POMATu

Я не впевнений на 100%, але я думаю, що призначення більше ядер розподіляє трафік віртуальної машини до кількості вибраних ядер
h0ch5tr4355

Вибачте за публікацію відповіді, яка не є відповіддю, але принаймні, поки ви чекаєте повної відповіді, я можу полегшити вашу роботу. Привітання.
MariusMatutiae

@ h0ch5tr4355 Я перевірю цю конфігурацію, але раніше я читав досвід, коли призначення більш ніж 1 ядру гостю VM фактично зробило гостьовий VM більш повільним. Так що я хотів би, щоб поширювати одне ядро ​​ВМ над ядрами, а не дозволяти будь-якої ВМ до повного 100% процесора хоста.
POMATu

Відповіді:


2

У мене немає відповіді на ваше запитання, але принаймні я можу полегшити ваш біль.

Якщо ви починаєте кожну віртуальну машину з командного рядка, наприклад,

VBoxManage startvm Name_of_VM --type headless

потім верхня команда з опцією -c відображатиметься також повна команда, яка запустила процес. Таким чином ви можете відразу визначити процес винуватця, і вбити його k опція всередині top себе (вам доведеться вказати номер процесу, який ви хочете вбити, який ви тільки що визначили).

Гарна річ , це працює, навіть якщо ви запускаєте всі ваші віртуальні машини з графічного інтерфейсу, а не з CLI.

EDIT:

По-друге, можливо, я знаю відповідь на ваше запитання. Я не впевнений, що це дійсно те, що ви шукаєте, в цьому випадку PLS просто скажіть мені так.

Утиліта Linux для обмеження виконання процесу на заздалегідь задане ядро taskset. Ви повинні мати його за замовчуванням, якщо не перевірити пакет util-linux. Ви можете відобразити цей процес спорідненість ( тобто , список cpus, на якому він дозволений для запуску, за допомогою

      taskset -cp Process_ID

( p прапор вказує, що далі слід номер процесу, c прапор замінює рядок символів на шістнадцяткове представлення процесорних ядер, що буде за замовчуванням.

Ви можете призначити вже запущений процес для запуску тільки на ядрах 0 і 1, наприклад, за допомогою

     taskset -cp 0,1 Process_ID

або запустити нову програму на ядрі 0 лише за допомогою:

      taskset -c 0 VBoxManage startvm Name_of_VM --type headless

Два застереження: по-перше, той факт, що ви обмежили процес для запуску на одному процесорі, не означає, що він буде єдиним процесом, який виконується на ньому: всі процеси, афінність яких включає в себе те, що процесор буде працювати протягом певної частини часу, це. Якщо ви хочете зарезервувати даний ЦП для ексклюзивного використання процесу, який ви встановили taskset, вам доведеться використовувати цей параметр isolcpus котрий ізолює даний ЦП від планувальника ядра . Просто додайте параметр isolcpus = [cpu_number] до командного рядка ядра Linux для завантажувача.

Крім того, слід зазначити, що обмеження процесу на один процесор не обов'язково має бути total solution що ви, здається, думаєте. Процесори використовують периферійні пристрої будь-якого типу і, за певних обставин, вони можуть застрягти, оскільки периферійні пристрої стають недоступними, що призводить до циклічного переходу процесора в запити, а шина і, можливо, периферійні пристрої перевантажуються запитами. Приклад? Я використовую контролер Sonos під керуванням Wine; коли я активую VPN, він відключається від своєї домашньої бази в Каліфорнії і продовжує затоплювати мою систему за допомогою мережевих запитів. Це не має нічого спільного з утриманням в одному процесорі.


Дякую! моє життя зараз набагато простіше! :) Почекаємо реальної відповіді зараз, тому що 1 VM не повинен уповільнювати всю систему хоста.
POMATu

Малий наконечник. Додавання nohup і & дозволити процесам по-справжньому безголового плавати у фоновому режимі: nohup VBoxManage startvm Name_of_VM --type headless &
JakeGould

Дякую! Тому я б просто написав скрипт, який поширює віртуальні машини над ядрами за допомогою цієї команди. Побачимо, чи допоможе це.
POMATu

@ MariusMatutiae Я зробив робочий сценарій на основі вашого рішення, спасибі
POMATu

0

За допомогою відповіді MariusMatutiae я нарешті зумів написати сценарій "spreader", який поширює всі запущені віртуальні віртуальні віртуальні машини на різні ядра. Крім того, він також робить те ж саме з 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

Якщо ви хочете, щоб вона працювала тільки з віртуальними машинами VirtualBox, видаліть [V]irtualBox.*comment\| з шаблону grep. Якщо ви хочете, щоб він працював тільки з VMware VM, видаліть \|.*[.]vm[x] з шаблону grep.

Відразу після застосування цього сценарію ви можете побачити деякі лаги у всіх віртуальних машинах протягом декількох секунд. Тоді все стане добре і працює як слід.

Тепер віртуальні машини не можуть з'їсти мій процесор, навіть якщо вони перевантажені, і Firefox дійсно радий їсти все це. Але це вже інша історія ...: /

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.