Почему большее количество ядер ЦП на виртуальной машине замедляет время компиляции?

17

[edit # 2] Если кто-нибудь из VMWare сможет достать мне копию VMWare Fusion, я буду более чем счастлив сделать то же самое, что и сравнение VirtualBox с VMWare. Почему-то я подозреваю, что гипервизор VMWare будет лучше настроен для гиперпоточности (см. Мой ответ тоже)

Я вижу что-то любопытное. По мере увеличения количества ядер на моей виртуальной машине с Windows 7 x64 общее время компиляции увеличивается, а не уменьшается. Компиляция обычно очень хорошо подходит для параллельной обработки, так как в средней части (пост-зависимое отображение) вы можете просто вызвать экземпляр компилятора в каждом из ваших файлов .c / .cpp / .cs / независимо от того, чтобы создать частичные объекты для компоновщика над. Так что я предположил бы, что компиляция будет очень хорошо масштабироваться с # ядрами.

Но то, что я вижу, это:

  • 8 ядер: 1,89 с
  • 4 ядра: 1,33 сек
  • 2 ядра: 1,24 с
  • 1 ядро: 1,15 с

Является ли это просто артефактом проекта из-за реализации гипервизора конкретного поставщика (type2: virtualbox в моем случае) или чем-то более распространенным среди большего количества виртуальных машин, чтобы сделать реализации гипервизора более простыми? С таким количеством факторов я, похоже, могу аргументировать как за, так и против такого поведения - поэтому, если кто-то знает об этом больше, чем я, мне было бы интересно прочитать ваш ответ.

Спасибо Сид

[ редактировать: адресация комментариев ]

@MartinBeckett: холодные компиляции были отброшены.

@MonsterTruck: не удалось найти проект с открытым исходным кодом для прямой компиляции. Было бы здорово, но я не могу напортачить прямо сейчас.

@Mr Lister, @philosodad: иметь потоки 8 hw, используя VirtualBox, поэтому должно быть отображение 1: 1 без эмуляции

@ Torbjorn: у меня есть 6,5 ГБ для виртуальной машины и небольшой проект VS2012 - маловероятно, что я обмениваю / удаляю файл подкачки.

@All: Если кто-то может указать на проект VS2010 / VS2012 с открытым исходным кодом, это может быть лучшей рекомендацией сообщества, чем мой (собственный) проект VS2012. Orchard и DNN, кажется, нуждаются в настройке среды для компиляции в VS2012. Я действительно хотел бы видеть, видит ли кто-то с VMWare Fusion также это (для разделения VMWare против VirtualBox)

Детали теста:

  • Аппаратное обеспечение: Macbook Pro Retina
    • Процессор: Core i7 @ 2.3Ghz (четырехъядерный, гипер поточный = 8 ядер в диспетчере задач Windows)
    • Память: 16 ГБ
    • Диск: 256 ГБ SSD
  • Хост ОС: Mac OS X 10.8
  • Тип виртуальной машины: VirtualBox 4.1.18 (гипервизор типа 2)
  • Гостевая ОС: Windows 7 x64 SP1
  • Компилятор: VS2012 компилирует решение с 3 проектами C # Azure
    • Измерение времени компиляции с помощью плагина VS2012 под названием «VSCommands»
    • Все тесты проводятся 5 раз, первые 2 запуска отбрасываются, последние 3 усредняются
DeepSpace101
источник
9
Возможно, файловый ввод / вывод замедляется из-за множества задач и доступа к диску на виртуализированном диске
Мартин Беккет
3
Я хотел бы воспроизвести это на моей собственной машине. Можете ли вы загрузить пример проекта где-нибудь? Я подозреваю, что виртуальная машина играет здесь. Попробуйте загрузиться с Windows (Bootcamp) и посмотрите, наблюдаете ли вы то же самое поведение - я сомневаюсь, что вы это сделаете.
Апурв Хурасия
1
Что мы здесь компилируем? Много времени на распараллеливание задачи не окупится, пока вы не достигнете определенного масштаба. Посмотрите, как работает компиляция apache или ravendb.
Уайетт Барнетт
2
Возможно, вам не хватает памяти на вашей виртуальной машине, поэтому она начинает меняться.
1
То же самое случилось со мной раньше с Java, использующим Maven 3.x для компиляции на i3. Разрешение по умолчанию для «4» потоков было намного медленнее, почти на 50% медленнее, чем явное указание использовать только 2 ядра. Я думаю, что это как-то связано с переключением контекста гиперпоточности и перекрывающимся вводом-выводом.

Ответы:

12

Ответ: Он не замедляется, он увеличивается с числом ядер ЦП. Проект, использованный в первоначальном вопросе, был «слишком маленьким» (на самом деле это тонна разработки, но небольшая / оптимизированная для компилятора), чтобы воспользоваться преимуществами нескольких ядер. Кажется, вместо того, чтобы планировать, как распределять работу, порождать несколько процессов компиляции и т. Д., В этом небольшом масштабе лучше начинать работу последовательно с самого начала.

Это основано на новом эксперименте, который я провел на основе комментариев к вопросу (и моего личного любопытства). Я использовал более крупный проект VS - исходный код Umbraco CMS, поскольку он большой, с открытым исходным кодом, и можно напрямую загрузить файл решения и перестроить (подсказка: загрузить umbraco_675b272bb0a3\src\umbraco.slnв VS2010 / VS2012).

ТЕПЕРЬ, то, что я вижу, - то, что я ожидаю, то есть компиляция увеличивается! Ну, до определенного момента, так как я нахожу:

Таблица результатов

Takeaways:

  • Новое ядро ​​виртуальной машины приводит к новому потоку OS X в процессе VirtualBox
  • Время компиляции увеличивается, как и ожидалось (время компиляции достаточно велико)
  • На 8 ядрах виртуальной машины эмуляция ядра может быть включена в VirtualBox, поскольку штраф огромен (50% попаданий)
  • Скорее всего, вышесказанное связано с тем, что OS X не может представить 4 ядра с гипер-резьбой (поток 8 ч / ш) как 8 ядер для VirtualBox

Этот последний момент заставил меня отслеживать историю процессоров по всем ядрам через «Activity Monitor» (историю процессоров), и я обнаружил, что

График истории процессора OS X

Takeaways:

  • На одном ядре виртуальной машины активность, похоже, перепрыгивает через 4 ядра HW. Имеет смысл распределять тепло равномерно по уровням ядра.

  • Даже на 4 виртуальных ядрах (и 27 потоках VirtualBox OS X или ~ 800 потоках OS X в целом) только четные потоки HW (0,2,4,6) почти насыщены, тогда как нечетные потоки HW (1,3,5,7) почти на 0%. Скорее всего, планировщик работает с точки зрения HW-ядер и НЕ HW-потоков, поэтому я предполагаю, что 64-битное ядро ​​/ планировщик OSX не оптимизировано для гиперпоточных процессоров? Или, глядя на настройку ядра 8VM, возможно, он начинает использовать их при высокой загрузке ЦП? Что-то смешное происходит ... ну, это отдельный вопрос для некоторых разработчиков Дарвина ...

[править]: Я хотел бы попробовать то же самое в VMWare Fusion. Скорее всего, это не будет так плохо. Интересно, продемонстрируют ли они это как коммерческий продукт ...

Footer:

В случае, если изображения когда-либо исчезнут, таблица времени компиляции (текст, уродливо!)

Cores in    Avg compile      Host/OSX    Host/OSX CPU
   VM         times (sec)   Threads      consumption
    1           11.83            24        105-115%
    2           10.04            25        140-190%
    4            9.59            27        180-270%
    8           14.18            31        240-430%
DeepSpace101
источник
Я подозреваю, что падение между 4 и 8 является комбинацией того, что виртуальная машина не оптимизирована для HT, и HT ни в коем случае не равен вдвое большему количеству ядер (в лучшем случае увеличение производительности на 30%, обычно гораздо меньше).
Даниэль Б
@DanielB: При 4 => 8 ядрах проблема не только в том, что это просто повышение на 30% (против + 100%), как вы и предполагали, а в том, что производительность на самом деле составляет -50%. Если бы аппаратные потоки были полностью «мёртвыми / бесполезными», а работа перенаправлялась на другие ядра, дельта производительности была бы равна 0. Поэтому я бы более склонен сказать, что это дизайн гипервизора VirtualBox типа 2. Интересно, как работает VMWare Fusion ...
DeepSpace101
«На одном ядре виртуальной машины активность, по-видимому, меняется между четырьмя ядрами HW. Имеет смысл распределять тепло равномерно на уровнях ядра» - не обязательно, как правило, лучше планировать на том же ядре (для кэша и т. Д.) но гипервизор просто выбирает одно ядро ​​или наименее используемое ядро, потому что считает его обработкой общего назначения, когда другие процессы используют эти ядра. В этом случае оптимизация планировщика работает против вас (но очень незначительно)
gbjbaanb
@Sid согласился, я просто указываю, что с HT вы получите (значительно) уменьшение отдачи намного раньше, чем вы думаете, если предположить, что это что-то вроде улучшения на 100%. В этом случае это может быть причиной вашего HD, что и послужило причиной моего раннего предложения по некоторым тестам искусственного процессора.
Даниэль Б
6

Есть только одна возможная причина, по которой это происходит: ваши накладные расходы превышают ваши выгоды.

Вы можете эмулировать несколько ядер, а не назначать реальные ядра или даже процессы или даже потоки с хост-машины. Это кажется мне вполне вероятным и, очевидно, даст вам отрицательное ускорение.

Другая возможность состоит в том, что сам процесс плохо распараллеливается, и даже попытка распараллелить его обойдется вам дороже в коммуникационных затратах, чем вы получаете.

philosodad
источник
your overhead is exceeding your gainsДа, но это в значительной степени охватывает все, не зная, что на самом деле вызывает это :) ... Я использую VirtualBox и имею физические ядра, поэтому предположим, что отображение должно быть 1: 1 без эмуляции. Я собираюсь искать БОЛЬШОЙ открытый исходный код VS2012, чтобы другие тоже могли ссылаться на него ... brb
DeepSpace101
@Sid согласно этому ответу superuser.com/a/297727 виртуальная машина ВМ должна использовать ядра хоста соответствующим образом. Но я все равно проверил бы, что происходит на хосте, чтобы убедиться, что происходит ожидаемое поведение.
Philododad
0

Ты не одинок ...

То же самое случилось со мной раньше с Java, использующим Maven 3.x для компиляции на i3. Разрешение по умолчанию для «4» потоков было намного медленнее, почти на 50% медленнее, чем явное указание использовать только 2 ядра.

Я думаю, что это как-то связано с переключением контекста гиперпоточности и перекрывающимся вводом-выводом.

Это имеет смысл, когда вы начинаете думать об этом. Вы можете доказать, что вызывает деградацию результатов, с помощью хорошего общесистемного инструмента профилирования.


источник