Оптимизация Сборки Большого Проекта

Практически все разработчики хотя бы раз в год сталкиваются с проблемой увеличения времени сборки проекта.

Сборка — медленный процесс, что особенно неприятно при использовании практики непрерывной интеграции с ее постоянными пересборками и сопутствующими действиями.

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

Но должны же быть способы сократить время сборки? Мы решили найти способ решить эту проблему.

Собираем за 60 секунд!.



Оптимизация сборки большого проекта

О том, чего нам в итоге удалось добиться, и пойдет речь в нашей теме.



Начинать

Залог успешной оптимизации проекта — его автоматизация.

Мы использовали известную систему автоматизации CMake, на которой, как на фундаменте дома, строили различные технологии.

Вот что у нас было в начале пути:

  • 176 проектов на C++ и C# (соотношение примерно 60% на 40%);
  • 100 МБ исходников;
  • 18 000 файлов (> 3 млн строк);
  • МСВС;
  • сервер (8 CPU, обычный диск на 10 HDD, рейд, 12 ГБ ОЗУ);
  • виртуальная машина.

Все это было собрано за 12 минут. После оптимизации кода по результатам статического анализа, удаления ненужных директив #include, перелинковки исполняемых модулей, динамических и статических библиотек время сборки сократилось до 8 минут. Далее мы поговорим конкретно об оптимизации процесса сборки, когда все возможные улучшения кода уже реализованы.

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

Как мы покажем далее, первое вовсе не исключает второе, а дополняет его.



Программный метод



Типичные методы
О стандартных способах настройки VisualStudio в Интернете написано немало, поэтому кратко их остановимся.

  • Переключатель /MP позволяет одновременно запускать несколько процессов компиляции.

  • Переключатель /Z7 отключает генерацию отладочной информации, что ускоряет компиляцию.

Более интересной является технология, известная как UnityBuild .

Это один из самых эффективных методов оптимизации программного обеспечения, ускоряющий сборку на 30%.

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

cmake каждого проекта использует модуль unity_build.cmake, который указывает на папку, содержащую все файлы *.

cpp, обрабатывает их и объединяет в новый «общий» файл *.

cpp. Затем создается файл *.

vcproj, содержащий этот единственный *.

cpp. Наша версия работает не совсем так.

В некоторых случаях (в частности, при работе с большим проектом) создание одного общего файла *.

cpp — не самый оптимальный вариант. Поэтому мы решили сгенерировать несколько файлов вместо одного большого.

Схематически это выглядит так:

Оптимизация сборки большого проекта

В результате использование нашей технологии Smart UnityBuild позволило ускорить сборку до 4 минут. 40 сек.



Оптимизация сборки большого проекта



UnityBuild + PCH (Incredibuild)
Очевидно, что использование PCH в связке с технологией UnityBuild, что называется, ничего не даст. Но есть еще способ обмануть VisualStudio. Для этого нужно искусственно переместить файлы, которые используются в проекте несколько раз (для нас это *.

boost и *.

spl) в отдельный проект, собрать из него Precompiled Headers и добавить их в основной проект, так как в результате VisualStudio «подумает», что это настоящие PCH. При использовании технологии Unity Build с Precompiled Headers и ключом LP можно добиться значительного сокращения времени сборки: в нашем случае с 12 минут. до 4 мин.

38 сек.

(без ключа ЛП - 5 мин.

53 сек.

).



Аппаратный метод

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

Вы также можете значительно ускорить процесс, оптимизировав аппаратное обеспечение сервера.



SSD RAID0 x 7
Лучший результат по времени сборки был достигнут при использовании 7 SSD-накопителей в массиве Raid0 и RAMDisk: время сборки проекта составило около 6 минут.

32 ЦП x 3 ГГц
Прирост производительности более чем в два раза по сравнению со стандартным значением времени (7 мин.

45 сек.

) при использовании 32 процессоров с технологией Hyper Threading (3 мин.

22 сек.

).



Оптимизация сборки большого проекта



Нижняя граница

Объединив все инструменты от опций Visual Studio до использования SSD-накопителей, мы смогли сократить время сборки проекта с 12 минут до 1 минуты.

45 сек.

Таким образом, заявленная цель — уложиться в 60 секунд — осталась невыполненной, но мы не расстроились :) Сокращение времени сборки проекта более чем в 6 раз — хороший результат. Вот как выглядит ход сборки нашего проекта:

Оптимизация сборки большого проекта

На диаграмме видно, что достижению еще большей скорости препятствуют несколько трудоемких процессов.

Это связывание больших модулей, которые нельзя распараллелить (только частичная попытка сделать это есть в MSVS 2012), но можно программно разбить их на несколько маленьких, уменьшив количество и размер статических библиотек.

Вот и все, собственно.

Нашей целью не было объять необъятное, и некоторые технические аспекты оптимизации не были включены в статью.

Мы готовы раскрыть подробности и ответить на все вопросы (в том числе по исходному коду cmake) в комментариях.

Спасибо за внимание! P.S. Мысли, высказанные в этой теме, легли в основу презентации, которую Виктор Стрелков (руководитель отдела исследований и контроля качества Positive Technologies) представил на конференции CEE-SECR в ноябре 2012 года.

Запись трансляции этого выступления можно посмотреть на сайте сайт мероприятия .

Теги: #оптимизация сборки #ускорение сборки #CMake #UnityBuild #PCH #incredibuild #clCache #Высокая производительность #Разработка веб-сайтов

Вместе с данным постом часто просматривают: