«Сколько еще ты будешь собиратьЭ» — фраза, которую хотя бы раз произносил посреди ночи каждый разработчик.
Да, сборка может затянуться надолго и от этого никуда не деться.
Нельзя просто взять и распараллелить всё это дело, не на каких-то жалких 8–12 ядрах, а так, чтобы было 100+.
Или это все еще возможно?
Мне нужно больше ядер!
Как вы могли заметить, сегодня мы поговорим о том, как ускорить компиляцию.И нет, на этот раз мы будем рассматривать не какие-то конкретные механизмы, а самое обычное распараллеливание.
Ну тут вроде бы всё просто — выставляем физически доступное количество ядер, нажимаем build и идём пить чай.
Но по мере роста базы кода время компиляции постепенно увеличивается и однажды оно станет настолько большим, что весь проект можно будет собрать только ночью.
Поэтому нам нужно подумать о том, как все это ускорить.
Довольные коллеги сидят и занимаются программированием, а их машины тихо и без усилий выводят на экраны небольшой текст. «Мы должны отобрать ядра у этих бездельников».
- ты можешь подумать.
И правильно сделали бы, ведь реализовать это вполне возможно.
Но, конечно, не нужно принимать мои слова близко к сердцу и вооружаться паяльником.
Впрочем, это на ваше усмотрение :)
Отдай это обратно!
Поскольку реквизировать машины коллег нам вряд ли кто-то позволит, воспользуемся обходными путями.Даже если вам удалось убедить коллег поделиться своим оборудованием, вы все равно не получите никакой выгоды от дополнительных процессоров, если не сможете выбрать тот, который быстрее.
И нам нужно решение, которое каким-то образом позволит нам запускать дополнительные потоки сборки на удаленных машинах.
К счастью, среди тысяч категорий всевозможного полезного программного обеспечения мы нашли то, что нам нужно — система распределенной сборки .
Программы этой категории делают именно то, что нам нужно: выдают на время неработающие ядра коллег и при этом делают это без их ведома в автоматическом режиме.
Разве что сначала нужно все это установить на свои автомобили, но об этом чуть позже.
Кого мы будем проверять?
Чтобы убедиться, что все работает действительно хорошо, нужно было найти качественного подопытного.Поскольку у нас уже не раз было в статьях и Хром И Линукс , но мне как-то хотелось выделиться, нужно было найти что-то новое.
Вот я и пошёл в сторону открытых игр (где ещё искать большие проекты?).
И как вы увидите ниже, я очень пожалел об этом решении.
Однако поиск чего-то не составил большого труда, и мне «посчастливилось» наткнуться на проект с открытым исходным кодом на Unreal Engine. Просто подумай об этом! Действительно, до момента написания этой статьи я даже подумать не мог, что на UE существует Open Source. Итак, герой этой статьи: Нереальный Турнир .
Только не спешите сразу переходить по ссылке, так как вам может понадобиться пара дополнительных кликов - подробности * здесь *.
Пусть будет сборка на 100+ ядер!
В качестве примера системы распределенной сборки Я, пожалуй, остановлюсь на IncrediBuild .Не то чтобы у меня был большой выбор — у нас уже была лицензия IncrediBuild на 20 машин.
Нет, конечно есть открытый distcc , но его не так-то просто настроить, к тому же почти все наши машины работают под управлением Windows. Итак, первое, что вам нужно сделать, это установить агенты на машины других разработчиков.
Есть два способа:
- спросите коллег в вашем местном Slack;
- воспользоваться полномочиями системного администратора.
Итак, теперь у меня было около 145 ядер (+/- 10) :) За исключением необходимости установки агентов (в установщике это делается в пару кликов), необходимо было установить координатор.
Это немного сложнее, поэтому я оставлю это ссылка на документы .
Итак, теперь у нас есть грид на стероидах, так что пора переходить к Visual Studio. Выбираем сборку в плагине.
А ее нет :) Если вы вдруг захотите попробовать сами, имейте в виду, что сначала вам нужно собрать проекты.
ШейдерКомпиляцияРаботник И UnrealLightmass .
Поскольку они не большие, я собирал их на месте.
Теперь можно нажать на заветную кнопку:
Так в чем же разница?
Как видите, нам удалось ускорить сборку с 30 минут до почти 6! Это совсем не так уж и плохо.
Кстати, запуск состоялся в середине рабочего дня, так что примерно таких же цифр можно ожидать и без синтетического теста.
Однако разница может варьироваться от проекта к проекту.
Что еще можно ускорить?
Помимо сборки, вы можете настроить IncrediBuild для любого инструмента, создающего множество подпроцессов.Как вы могли заметить, я работаю в PVS-Studio. Поэтому, конечно, я не могу игнорировать возможность скормить ему наш анализатор.
Выгода от быстрого анализа примерно такая же, как и от быстрой сборки: возможность локальных прогонов перед коммитом.
Конечно, всегда есть желание загрузить все сразу в мастер; но обычно тимлид такие действия не рад, особенно когда на сервере ночные забеги.
Поверьте - я уволился :( Специально настраивать анализатор нет необходимости, разве что нам не мешало бы указать в настройках старые добрые 145 потоков:
Ну и стоит указать локальной системе сборки, кто является анализатором:
Подробности * здесь * Итак, пришло время снова нажать на сборку и насладиться ускорением:
Прошло около семи минут, что подозрительно похоже на время сборки.
Потом я подумал, что видимо забыл добавить флаг.
Зашёл в настройки и увидел, что всё на месте.
Такого я не ожидал, поэтому пошёл курить мануалы.
Попытка запустить PVS-Studio #2
Через некоторое время я вспомнил версию Unreal Engine, которая используется в этом проекте:Не то чтобы это само по себе плохо, но флаг -StaticAnalyzer появился гораздо позже.
Поэтому нельзя сказать, что можно интегрировать напрямую.
Примерно в этот момент я уже начал подумывать о том, чтобы бросить все это дело и пойти выпить кофе.
После пары кружек бодрящего напитка мне пришла в голову мысль дочитать руководство по интеграции и до конца.
Помимо вышеописанного метода существует еще и мониторинг компиляции.
Это именно тот вариант, когда больше ничего не помогает. Первым делом включим сервер мониторинга:
Эта штука будет работать в фоновом режиме и следить за вами с помощью вызовов компилятора.CLMonitor.exe monitor
Но он не может следить за тем, что происходит в IncrediBuild, поэтому его придется один раз собирать без него.
По сравнению с предыдущим запуском локальный ребилд выглядит очень бедно: Total build time: 1710,84 seconds (Local executor: 1526,25 seconds)
Теперь сохраним собранное в отдельный файл: CLMonitor.exe saveDump -d dump.gz
Вы можете продолжать использовать этот дамп, пока не добавите в проект новый файл.
Да, это не так удобно, как с флагом, но ничего не поделаешь — версия движка слишком старая.
Сам анализ запускается такой командой: CLMonitor.exe analyzeFromDump -l UE.plog -d dump.gz
Только не запускайте его так, потому что мы хотим запустить его под IncrediBuild. Итак, давайте вставим эту команду анализировать.
bat. И создайте файл рядом с ним профиль.
xml : <Эxml version="1.0" encoding="UTF-8" standalone="no" ?>
<Profile FormatVersion="1">
<Tools>
<Tool Filename="CLMonitor" AllowIntercept="true" />
<Tool Filename="cl" AllowRemote="true" />
<Tool Filename="PVS-Studio" AllowRemote="true" />
</Tools>
</Profile>
Подробности * здесь * И теперь мы можем запускать все на наших 145 ядрах: ibconsole /command=analyze.bat /profile=profile.xml
И как это выглядит в Build Monitor:
В этом графике много ошибок, не так ли? К нам закралась еще одна проблема.
И на этот раз дело не в том, что кто-то что-то не поддерживает. Сборка Unreal Tournament получилась несколько специфичной.
Пытаюсь запустить PVS-Studio #3
Если внимательно посмотреть, то это не ошибки анализа, а сбои во время предварительной обработки исходного кода .
Причем причина этой неудачи была одна и та же: .
\Build.h(42): fatal error C1189: #error: Exactly one of [UE_BUILD_DEBUG \
UE_BUILD_DEVELOPMENT UE_BUILD_TEST UE_BUILD_SHIPPING] should be defined to be 1
Так в чем проблема? Все довольно просто — препроцессор требует, чтобы только один из следующих макросов имел значение 1:
- UE_BUILD_DEBUG;
- UE_BUILD_DEVELOPMENT;
- UE_BUILD_TEST;
- UE_BUILD_SHIPPING.
Пришлось покопаться в логах, а точнее в дампе компиляции.
Вот где проблема была найдена.
Дело в том, что эти макросы объявлены в локальном файле.
прекомпилируемый заголовок , и нам нужна только предварительная обработка.
Поэтому мне пришлось добавить все эти макросы вручную: #ifdef PVS_STUDIO
#define _DEBUG
#define UE_BUILD_DEVELOPMENT 1
#define WITH_EDITOR 1
#define WITH_ENGINE 1
#define WITH_UNREAL_DEVELOPER_TOOLS 1
#define WITH_PLUGIN_SUPPORT 1
#define UE_BUILD_MINIMAL 1
#define IS_MONOLITHIC 1
#define IS_PROGRAM 1
#define PLATFORM_WINDOWS 1
#endif
Самое начало файла build.h И с помощью этого маленького костыля, элегантного решения, можно начать анализ.
Причём сборка не сломается, так как мы использовали макрос PVS_STUDIO. Итак, долгожданные результаты анализа:
Согласитесь, почти 15 минут вместо двух с половиной часов – это очень неплохое ускорение.
Трудно представить, что можно пить кофе 2 часа подряд и ни у кого в тебе не возникнет сомнений.
Но 15-минутный перекур не вызывает никаких вопросов.
Может быть.
И что мы имеем в итоге?
Конечно, в идеальном мире увеличение количества потоков в Н увеличит скорость сборки в разы Н один раз.Но мы живем совсем в другом мире, поэтому стоит учитывать локальную нагрузку на агентов (удаленные машины), нагрузку на сеть, время на организацию всего этого дела и еще много деталей, которые спрятаны под капотом.
Однако ускорение действительно есть, и кое-где оно позволяет не просто запускать полную сборку или анализ раз в день, а делать это гораздо чаще.
Например, после каждого исправления или перед фиксацией.
А теперь предлагаю посмотреть, как это все выглядит в одной таблице:
Я запустил его пять раз и посчитал среднее по запускам (эти цифры вы видели на графиках) :) В опросе могут участвовать только зарегистрированные пользователи.
Войти , Пожалуйста.
Вы используете IncrediBuild? 14,29% Да 3 85,71% Нет 18 Проголосовал 21 пользователь.
10 пользователей воздержались.
Теги: #разработка #DevOps #C++ #исследования #инструменты #pvs-studio #unreal engine #статический анализ #верификация #unrealengine #incredibuild
-
Декодирование Сири
19 Oct, 24 -
Использование Rabbitmq С Monstermq, Часть 3
19 Oct, 24 -
Батарея Стива Балмера
19 Oct, 24 -
Очень Странно
19 Oct, 24