Как ускорить сборку 1000 VisualStudio C++ проектов

    Добрый день, уважаемые хабраюзеры.
    Я решил написать этот топик, чтобы не не копировать мой комментарий к данному посту. Здесь я просто опишу наше решение

    До изменений:
    Полная сборка (clean) занимала около 4.5 часов
    Инкрементальная сборка (continuous) занимала около 30 минут.
    После изменений:
    Полная сборка — около 40 минут.
    Инкрементальная сборка — 2-3 минуты


    Входные данные:
    Железо (dedicated builder machine): Intel Xeon E5430@2.66Hz, 4 GB RAM
    Среда разработки: Windows XP, 2003, 7, 2008. VisualStudio 6, 2005, 2008, 2012.
    Сборка включает в себя около 1000 C++ проектов: ~3MLN LOC

    Как это работало:
    У нас был файл, котрый содержал список проектов которые должны быть скомпилированы в порядке очередности.
    Сборочный скрипт проходил по этому файлу и запускал компиляцию каждого проекта по-очереди.
    Соответственно, время сборки росло из месяца в месяц линейно к количеству проектов, и в какой-то момент, перестала нас устраивать категорически.

    Что было поменяно:
    • Замена дисков на SSD (до этого были неплохие HDD диски от WD)
    • Интеграция IncrediBuild в сборочный скрипт. Incredibuild мы установили на 4 компа. (тривиальное изменение, если у вас уже есть сборочный скрипт)
    • Компиляция одного огромного solution с прописанными зависимостями. Solution генерируется автоматически на основании списка проектов и файла зависимостей для каждого проекта
    • Еще одно существенное ускорение процесса сборки, хотя и не имеющее отношение к скорости компиляции, нам дал перехед на svn 7 (только client). Особенно сильно это сказывается на инкр. сборке, когда надо сделать update огромной working copy. С svn 7, время упало с 10 минут до 1 минуты.
    Сразу замечу, что, к сожалению, я не могу описать точный эффект от каждого изменения, так как все было поменяно за один раз.
    По-ощущениям, каждое изменение ускорило сборку в 2-3 раза.

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

    Надеюсь, что кому-нибудь наш опыт может показаться полезным.
    Поделиться публикацией

    Комментарии 51

      +8
      А в чем необходимость иметь такое количество проектов? Я так понимаю они взаимосвязаны, раз вы собираете сразу все вместе.
        +3
        Ну причины стандартные, я думаю. На уровне програмистов, это переиспользование кода — библиотеки, быстрее компиляция — в процессе разработки не надо компилировать лишний код, модульность, в конце концов — легче ориентироваться в коде. На уровне тестов и проектов — легче логистика: можно локально поменять один два ДЛЛ чтобы проверить какое-нибудь изменение.
        (сорри, первый раз ответил не в той ветке)
        +3
        Ну причины стандартные, я думаю. На уровне програмистов, это переиспользование кода — библиотеки, быстрее компиляция — в процессе разработки не надо компилировать лишний код, модульность, в конце концов — легче ориентироваться в коде. На уровне тестов и проектов — легче логистика: можно локально поменять один два ДЛЛ чтобы проверить какое-нибудь изменение.
          –5
          Чего только не придумают чтобы не написать пару makefiles ;-)
            +2
            Я бы с удовольствием написал даже две пары makefiles. Не подскажете, что именно надо делать?
              +9
              Я бы посоветовал для начала почитать про maven.

              Есть подозрение, что это именно ваш случай, и да — он умеет работать с С++. Вместо пересборки всего и вся описываете все ваши библиотеки как артефакты и складываете в репозиторий. Оно само отследит версии, зависимости и прочее, а после компиляции еще и сделает доступным результаты. Пересобирать постоянно гору библиотечек на вашей рабочей машине — не придется, только то над чем вы работаете.

              mvn install
              


              и горы кода внезапно доступны любому в команде в уже собранной форме, причем всегда свежие.

              Работа программистов станет намного комфортнее, и скорость пересборки проекта вас волновать перестанет (если бы и линкер не был таким тормозом — был бы рай).

              Один минус — не поддерживается в вижуалстудии.

              Ну и про makefile (я утрирую, начинать надо бы хотя бы со SCons, а не с этого рашпиля):

              all: <все подкаталоги, синтаксис зависит от варианта Make>
              
              # тут зависимости в простой форме, именно то что вы выявляли
              
              A: B C D
              
              B: C D
              
              C: ...
              


              запускаем нечто вроде

              CC=distcc gmake -j 
              


              Но опять же — не поддерживается вижуалстудией (максимум — makefile все еще можно сделать из проекта, но под диалект nmake. Далее — руками).

              Вы меня не слушайте, я старый хардкорщик, программирующий в фаре, и не понимаю — как это можно вошкаться с солюшенами единственно правоверной оболочки, когда есть столько полезных средств, упрощающих жизнь ;-)

              Ну а если у вас заработает maven — можно будет вспомнить и про Hudson, и закатывание солнца вручную больше не потребуется.
                +1
                Это да. Для начала стоило бы почитать про MSBuild, потом про Makefile, потом scons/gyp+ninja/etc., и придти к Maven. И к Jenkins.
                  0
                  У описанного вами пути есть один недостаток — долго. Правильно, логично, академично — но долго. Поэтому я и предложил сразу начать с мавена, а уж уперевшись в его ограничения — переходить к «под капотом».
                  +1
                  VC++ проекты уже давно суть MSBuild-мейкфайлы, с зависимостями, параллелизацией и прочим. Причем solutions для разруливания зависимостей не нужны, это чисто VS-артефакт, а так можно просто запустить MSBuild на файл проекта, который выдает конечный результат, и все зависимости построятся автоматом.
                    0
                    Совершенно верно! К сожалению, только начиная с Visual Studio 10, а мы еще должны поддерживать более старые версии.
                    0
                    У нас на работе такая же система, есть специальный репозиторий скомпилированных библиотек и сторонних компонент (артефактов).
                    Зависимости прописываются в простых конфигурационных файлах вида package=version.

                    Репозиторий работает на artifactory
                      0
                      Не планируете пост на эту тему? Ну или хотя бы тут, по-подробнее? Мне было бы очень интересно узнать как у вас это организовано, особенно про артифактори.
                        0
                        Я только перешел в этот отдел, еще не всё понял. Если разберусь за неделю-две, то напишу.
                      0
                      Спасибо, очень интересно, серьезно, особенно учитывая что я даже более старый хардкорщик и понимаю толк в подобных извращениях.
                      Честно говоря, мне кажется, что Ваше решение не очень жизнеспособно для реальной жизни.
                      Как минимум Вы получите огромное количество геморроя при использовании сторонних библиотек и фрэймворков,
                      которые поставляются в виде проектов для вижуал студио.
                      Кроме того, не сможете использовать IDE со всеми плюшками типа complete/browse to, и т.д.

                      Я прилично знаю мавен — кроме 1000 c++ проектов, мы компилируем еще столько же java проектов и тоже со сложными зависимостями, но и там мы не пользуемся мавеном, а написали свой таск для анта, который строит дерево зависимостей и компилирует проекты в нужном порядке. Лично мне мавен кажется черезчур монстроидальным.
                      Не знаю почему Вы упомянули именно Хадсон, мы пользуемся CruiseControl на наших 10 билдерах, просто когда я настраивал ContinuosIntegration, Хадсона по-моему не существовало, или он был очень слаб. Не говоря уж о новорожденном Дженкинсе.

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

                      Ну и, конечно же, никто не пересобирает гору библиотек на собственной машине. Все бинарники, сгенерированные билдером, доступны с помощью (опять-таки) пары самописных скриптов.
                        0
                        > Честно говоря, мне кажется, что Ваше решение не очень жизнеспособно для реальной жизни.

                        Мы используем, удобно, быстро, практично.

                        > Как минимум Вы получите огромное количество геморроя при использовании сторонних библиотек и фрэймворков,
                        которые поставляются в виде проектов для вижуал студио

                        Есть проект для вижуалстудии, нет проекта для вижуалстудии… pom.xml на 15 строк нарисовать методом скоростного копипаста дело пары минут (больше всего при этом времени тратим на придумывание удобного artifactId). Вот если бы вы упомянули «конфигура на перле» — это аргумент. Приходится вспоминать мануал — как там предобработку-то задавать и прочее ;-) Да и то — это актуально если есть еще какие-то платформы, кроме единственной.

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

                        > Кроме того, не сможете использовать IDE со всеми плюшками типа complete/browse to, и т.д.

                        Это с какого перепугу? debug=«true» и пробки в потолок ;-)

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

                        >… доступны с помощью (опять-таки) пары самописных скриптов

                        вот именно. Работает — не трогаем, пока не рухнет под собственной тяжестью.

                        > Не знаю почему Вы упомянули именно Хадсон

                        Он лично мне более симпатичен, чем архаичный круиз.
                          0
                          Т.е. Вы предлагаете мне разобраться в скриптах компиляции библиотек типа стингрея, опенсиви, оспейса, и тд, приготовить для них помы, и поддерживать все это дело для новых версий, и все для того чтобы не пользоваться visual studio, програмировать в notepad++?
                          И при этом, cruisecontrol для Вас архаичен, a мои скрипты для копирования артефактов скоро упадут под собств. тяжестью? Вы действительно работаете в большом проекте?
                            0
                            А я к вам с утюгом приехал — уговаривать скрипты сменить? Пользуйтесь на здоровье.

                            Я вам рассказал про свой опыт, вы про свой. Нам проще обернуть 3rd party библиотеки в свою билд-систему, вам — мышой возить. Каждому свое. Когда-то — мы шли по вашему пути, потом решили напрячься и перейти на другой. Почему — я намекнул. Стройная система скриптов и подпорок стала слишком часто давать сбой.

                            Вы умеете лучше нас не наступать на грабли? Мои поздравления.

                            Или вас лично задели мои вкусы? Тут извините, ничем помочь не могу.
                  +1
                  Разбиение на много мелких независимых компонентов — это правильно. Даже немного завидно, т.к. у нас все строго наоборот.
                    +1
                    Лучше деньги вместо ссд потратить на лицензии на инкредибилд и установить на значительно большее кол-во тачек — т.е. поставить его всем, даже секретарше. Вот тогда будет реально круто. На моей прошлой работе с таким подходом проект компилировался на 30+ ядрах, что в суме давало около 100 ГГц. Кода больше чем у вас, полный ребилд делался за 10-14 минут, из них минуты 3-4 это линковка на локальной тачке
                      +1
                      10-14 минут, и кода «больше чем у нас» — это очень хороший результат, респект Вам и уважуха.
                      Для нас лучше и IncrediBuild и SSD вместе: IncrediBuild на больше чем 4-х машинах производительности не добавил.
                      Мы его пробовали еще до SSD. Проблем ни с лицензиями, ни с машинами для билдов у нас нет.
                        +1
                        10-14 минут это очень офигенный результат. На позапрошлой работе был такой же громадный проект, игра на UE3, но без инкредибилда. И это был кошмар. Не дай бог добавишь\удалишь переменную в скриптах — ждешь перекомпиляции всех скриптов 7 минут, оно генерирует один большой хедер на 100к+ строк, где располагаются ВСЕ классы ну и потом собираешь его на 4-х ядрах Core 2 Quad на 2.7 ГГц где-то 20-30 минут. Полный ребилд всего проект делал только один раз. Сколько это занимало по времени — не скажу, по памяти где-то полтора-два часа.
                        З.Ы. Есть еще open source аналог инкредибилда — code.google.com/p/distcc/ Хотя я его не щупал. Все хочу свой open source аналог для студии сделать, но никак руки не доходят из-за основного проекта
                          0
                          distcc же для Windows не годится вроде? А IncrediBuild плагин для студии чем-то Вам не понравился, или из-за того что он платный не хотите им пользоваться?
                            0
                            distcc же для Windows не годится вроде?
                            Ага.

                            А IncrediBuild плагин для студии чем-то Вам не понравился
                            Мне он всем нравится. Кроме цены :)
                              0
                              Сам distcc — нет. Но можно использовать distcc + mingw для сборки для Windows на linux машинах.
                                0
                                Про извращения я ответил тут.
                                Такими вещами, конечно, очень приятно заниматься, но насчет жизнеспособности у меня сомнения
                                  0
                                  Если бы я работал программистом, то я бы вряд ли поставил на работе такую систему. А дома — почему бы и нет? Останавливает только то, что единственная машина, на которой имеет смысл ставить distcc в качестве сервера, является единственной же, на которой мне когда‐либо требуются самостоятельно собранные exe’шники для windows (wine).
                          0
                          Доброго времени суток, у меня к вам вопрос по поводу IncrediBuild вот какого характера: насколько сильно он тормозит процесс линковки?
                            0
                            Линковка это процесс который нельзя распараллелить, потому она происходит исключительно на локальной тачке. Ну и, собственно, сам инкредибилд этот процесс никак не тормозит :)
                              0
                              Это так, просто IB запускает линкер в контейнере, и в последний раз когда его пробовал с ним процесс линковки терял до 10% производительности, скорее всего это баг был. А сейчас он у меня вообще не собирает ничего на Win Server 2008r2, ругаясь, что ему для сборки нужна ОС Vista+ :)
                                0
                                4.6? буквально вчера заапгрейдил один из билдеров и получил какие-то странные ошибки. еще не было времени посмотреть.
                                3.х отлично работал на Win Server 2008r2.
                                  0
                                  Агу, он самый :(
                                    0
                                    Отпишитесь пожалуйста если найдёте решение проблемы.
                            0
                            Не пробовали сборку на RAM диске? Установочную папку VS и TEMP директорию нужно перенести туда же.
                              0
                              Пробовал только ТЕМП, ощутимо не помогло. Бинарники — результаты компиляции — на РАМ диск не вынести все равно, там около 10 Гб…
                              Сейчас, пока писал ответ, подумал, что, наверное, можно поиграться с асинхронным переносом результатов компиляции с РАМ диска на обычный, может, в следующий раз попробую, если опять слишком долгим все покажется. Пока 2-3 минуты время отзыва от «continuous integration», и 1 час ночью улучшать неохота:).
                                0
                                Сейчас память очень дешевая. Исходя из специфики задачи (так как сохранность не важна в принципе, всё есть в SVN) — то эффективнее всё держать на рамдиске, и забыть о ССД.

                                Я думаю (не проверял): Если смотреть по самому эффективному способу вложения в билдфактори — то это бездисковые i5 с 32Gb ram. По крайней меле для linux сборок, но думаю что в VS принципы те-же.
                                Где-то я видел статью, там где с помощью нескольких простых скриптов и rabbitMQ была сделана распределённая билд фактори.
                                  0
                                  На тот момент, мы должны были компилировать на Windows 2003, которые не поддерживают более 4ГБ (Enterprise Еdition не в счет из-за цены). Сейчас уже нет такого ограничения, но 32 ГБ нам тупо не хватит. Нам надо минимум 100 ГБ для всех соурсов, библиотек, бинарников, сетапов, и т.д., да и SSD дешевеют. Хотя тема несомненно интересная.
                                    +1
                                    — Запустите во время компиляции ProcMon, посмотрите нагрузка на какие именно файлы идет. VS достаточно много своих библиотек использует.
                                    — Попробуйте зафиксировать processor affinity для ОС на первое физическое ядро (это первые 2 виртуальных ядра), VS на все остальные, чтобы не происходило спонтанное переключение между ядрами.
                                    * Можно попробовать зафиксировать частоту на уровне который используется при Hyperthreading, а его собственно отключить вместе с режимом энергосбережения.
                                    — Настройте правильно SSD, есть более 20 различных настроек которые влияют на его производительность :)
                                    Как минимум: подключайте только к Intel контроллеру, выключите файл подкачки, hibernate.
                                    — Если будете менять процессор, то выберите нормальную память: минимум DDR3-1600 (лучше DDR3-1866+), если у вас LGA115x то 2 планки (если LGA2011 то 4 планки)

                                    Ну и самое главное: замерьте влияние каждого изменения по отдельности от исходной конфигурации, и только потом попробуйте их скомбинировать.
                                      0
                                      Круто! Но я не владею вопросом настолько, к сожалению. Надеюсь что наши админы все это знают (или хотя бы способны понять все слова :) )
                              +1
                              А Qt Build Suite не пробовали?
                                0
                                Я пробою.
                                Пока он как то странно начинает пересобирать приложения при изменении в одной из библиотек проекта.
                                Конкретное приложение от этой библиотеки не зависит, но начинаешь ее менять — пересобирает всё подряд практически.
                                На синтетике пока поймать не удалось, как руки дойдут сделать — выложу в рассылку.

                                В общем, моё мнение — сыроват qbs пока. Хотя перспективы неплохие.
                                  0
                                  Да, сыроват. Мы с ребятами пробовали, нашли пару багов, решели пока подождать и сидим на CMake.
                                  Но, в целом, задумка хорошая.
                                    0
                                    Сейчас у меня сборка на msbuild. Последовательно собирается несколько sln проектов. Мне очень хочется от этого уйти, вот и смотрю разные варианты сборщиков. Qbs вроде как самый подходящий, т.к. проект полностью на Qt.

                                    Вот как бы ещё распараллелить сборку нескольких Inno Setup дистрибутивов.
                                    А то сейчас сборка дистрибутивов занимает 50% от сборки всего проекта.
                                      0
                                      Попробуйте объеденить все проекты в один общий слн, и компилируйте его. VS 10 и выше компилирует параллельно. Или воспользуйтесь incredibuild.
                                      Для InnoSetup напишите аппликацию, которая запускает несколько сборок одновременно через exec.
                                0
                                Я за месяц работы походил по всем граблям и по максимуму задействовал софтовые способы ускорения сборки:
                                — Отказался от MSBuild в пользу ninja, благо оригинальный проект в gyp и генерируется что угодно.
                                — Включил компонентную сборку.
                                — Установил msysgit из ветки fscache, который кеширует обращения к файловой системе на винде.
                                — Включил clcache (оригинальный немного недопилен, я использую форк, моего коллеги — github.com/vchigrin/clcache/
                                  0
                                  Доброго времени суток, у меня к вам вопрос по поводу IncrediBuild вот какого характера: насколько сильно он тормозит процесс линковки?
                                    0
                                    del

                                    всё, мне спать пора. Прошу прощения.
                                    0
                                    Замена на ССД? Дык — давно пора, темболее что листингов много, как я понял, я вот тоже с начальства на рабочую тачку начну себе диск без механики выпрашивать, коллеги не нарадутся у кого есть.
                                      0
                                      Несколько лет назад использовали IncrediBuild, правда, на девелоперских машинах. Но столкнулись с проблемами, по-моему, связаными с невозможностью нормального дебага на полученных бинарниках. Сейчас пришли к такой схеме: есть несколько build серверов, отдельно для релизов и дебагов. Настроен continuous integration билд c помощью CruiseControl и MSBuild. Разработчики могут стянуть свежие бинарники вместе с pdb из сетевого хранилища с помощью скрипта и нужно пересобирать лишь один проект, который они правят. Полный ребилд всего солюшена (многопоточный, на выделенном сервере) занимает 3 часа 30 минут. Там же настроены ночные билды и запуск юнит тестов.
                                        0
                                        У нас точно такая же система, только билд делается с IncrediBuild, никто на дебаг не жалуется.
                                        IncrediBuild установлен только на серверах.
                                          0
                                          Возможно у нас проблемы были из-за того что у разработчиков различались пути установки студии и дополнительных библиотек. У вас же всё единообразно на серверах. С другой стороны, я не вижу смысла в его использовании на сервере, т.к. там билд распараллеливается стандартными средствами.
                                          А так, во времена 6-ой студии, было весело наблюдать как всё быстро собирается на 20 компах, в то время это действительно давало существенный прирост.
                                        0
                                        С другой стороны, я не вижу смысла в его использовании на сервере, т.к. там билд распараллеливается стандартными средствами.

                                        Стандартные средства не распараллеливают на несколько машин.

                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                        Самое читаемое