Подтвердить что ты не робот

Время сборки GCC не сильно выигрывает от предварительно скомпилированных заголовков

У меня есть огромный проект, около 150 000 LOC кода С++. Время сборки составляет около 15 минут. Этот проект состоит из множества подпроектов разных размеров.

Я построил отдельные предварительно скомпилированные заголовки для каждого подпроекта, но когда я использую их, время сборки остается примерно одинаковым. Казалось, что время сборки на 5-10% меньше, а не больше.

Предварительно скомпилированные заголовки определенно используются, я использую параметр -Winvalid-pch, и я попытался скомпилировать с опцией -H компилятор, мои прекомпилированные заголовки появляются на выходе с символом "bang", это означает, что компилятор может использовать предварительно скомпилированный заголовок.

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

Есть ли свободные/открытые исходные инструменты для оптимизации сборки? Казалось, что стандартная утилита make не имеет возможности измерять времена сборки разных целей. Я не могу найти способ получить статистику для разных целей с помощью make. Я не говорю об анализе зависимостей или о чем-то продвинутом. Я просто хочу знать, какие цели большую часть времени были потрачены впустую.

Кроме того, казалось, что GCC довольно неэффективен в работе с прекомпилированными заголовками. Мне не удалось получить какую-либо сборку подпроекта заметно быстрее, максимальное ускорение, которое я получаю, составляет 20% от проекта, который получает три минуты на сборку. Казалось, проще и дешевле купить более быструю машину с твердотельным диском, чем оптимизировать время сборки на Linux с помощью GCC.

4b9b3361

Ответ 1

Если вы хотите получить максимальную отдачу от этой функции, вам нужно понять, как ваши проекты могут быть структурированы для их эффективного использования. Лучший способ - медленный, жесткий процесс ручного сокращения времени сборки. Сначала звучит глупо, но если все сборки идут вперёд в 5 раз быстрее, и вы знаете, как структурировать ваши проекты и зависимости, двигаясь вперед - тогда вы осознаете выигрыш.

Вы можете настроить систему непрерывной интеграции с вашими целями для измерения и записи ваших достижений/улучшений по мере внесения изменений.

У меня есть огромный проект, около 150 000 LOC кода С++. Время сборки составляет около 15 минут. Этот проект состоит из множества подпроектов разных размеров.

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

Также рассмотрите время ссылки.

Все мои предварительно скомпилированные заголовки не очень большие, каждый файл имеет около 50 МБ.

Это довольно большой, ИМО.

Я не говорю об анализе зависимостей или о чем-то продвинутом.

Опять же, непрерывная интеграция для статистики. Для сборки, которая медленная, чрезмерные зависимости, скорее всего, являются проблемой (если у вас нет большого количества небольших файлов cpp или что-то глупое, как изнурение физической памяти).

Мне не удалось получить какую-либо сборку подпроекта заметно быстрее, максимальное ускорение, которое я получаю, составляет 20%

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

Казалось, проще и дешевле купить более быструю машину с твердотельным накопителем, чем оптимизировать время сборки на Linux с помощью GCC.

Скорее всего, эта машина не будет увеличивать время сборки на 20 раз быстрее, но исправление зависимостей и структур проектов может сделать ее 20 раз быстрее (или, в любом случае, корень проблемы в конечном счете). Машина помогает только так (учитывая время сборки для 150KSLOC).

Ваша сборка, вероятно, связана с ЦП/памятью.

Ответ 2

Время сборки GCC не сильно выигрывает от предварительно скомпилированных заголовков

Да, к сожалению, это часто верно,

Есть несколько экспериментальных проектов, чтобы сделать что-то лучше, см. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3426.html и http://gcc.gnu.org/wiki/pph, но они еще не используются.

Я согласен с другим ответом, что 15 минут для 150KLOC довольно медленные.

Я обнаружил, что использование компоновщика Gold имеет огромное значение для создания времени, я настоятельно рекомендую его.

Вы также можете рассмотреть ccache, который может помочь, и если у вас есть запасные циклы на других машинах distcc

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

И это, возможно, само собой разумеется, но основывается на многоядерной машине и использует make -j N, где хорошее эмпирическое правило состоит в том, что N должно быть в два раза больше ядер или больше, если компиляция связана с I/O.

Ответ 3

Я использую -include при создании и использовании PCH для включения файла, который содержит множество заголовков. Это помогает, но это все еще не так впечатляет.

Считайте ваши благословения, однако: gcc выглядит в несколько раз быстрее, чем, скажем, MSVC, хотя MSVC имеет лучшую поддержку PCH.