Мы разрабатываем Библиотека C ++ в настоящее время более 500 сотен отдельных файлов .cpp. Каждый из них компилируется и архивируется в статическую библиотеку. Даже при параллельной сборке это занимает несколько минут. Я хотел бы сократить это время компиляции.
Каждый файл состоит в среднем из 110 строк с функцией или двумя внутри. Однако для каждого файла .cpp существует соответствующий заголовок .h, который часто включается во многие файлы .cpp. Например, A.h
может быть включен A.cpp
, B.cpp
, C.cpp
, и так далее.
Я бы сначала хотел профиль процесс компиляции. Есть ли способ узнать, сколько времени тратится на то, что делать? Я беспокоюсь, что много времени тратится впустую, открывая заголовочные файлы только для проверки включаемых защит и игнорирования файла.
Если такого рода вещи являются виновником, каковы лучшие методы для сокращения времени компиляции?
Я готов добавить новые групповые заголовки, но, вероятно, не желаю изменять этот макет с несколькими файлами, поскольку это позволяет нашей библиотеке также функционировать как по мере необходимости библиотека только для заголовков.
Если такого рода вещи являются виновником, каковы лучшие методы для сокращения времени компиляции?
Если ваш препроцессор поддерживает #pragma once
директива, используйте это. Это гарантирует, что файл .h не будет прочитан более одного раза.
Если нет, используйте #include
охранники в .cpp файлах.
Скажи у тебя
хиджры:
#ifndef A_H
#define A_H
...
#endif
Вы можете использовать следующий метод в A.cpp:
#ifndef A_H
#include "A.h"#endif
Вам нужно будет повторить этот шаблон для каждого файла .h. Например.
#ifndef B_H
#include "B.h"#endif
#ifndef C_H
#include "C.h"#endif
Вы можете прочитать больше об использовании #include
охранники в .cpp файле на Какова функция include guard в .cpp (не в .h)?.
Я не знаю, делаете ли вы это уже, но использование предварительных объявлений вместо включений в заголовки должно увеличить скорость компиляции. Смотрите этот вопрос для получения дополнительной информации:
Следует ли использовать предварительные декларации вместо включений везде, где это возможно?
Другой способ уменьшить время компиляции — использовать ccache
, Кэширует результаты предыдущих компиляций.
Это действительно трудно сказать.
Я работал над улучшением времени компиляции нашего проекта на работе и обнаружил, что один файл занял 15 минут (при компиляции в -O2
, но около 15 секунд -O0
) и компилируется дважды, поэтому для общего времени компиляции около 60-70 минут это было примерно вдвое меньше. Отключение ОДНОЙ функции оптимизации привело к тому, что один файл сократился до 20 секунд вместо 15 минут … Этот файл создавал одну функцию, сгенерированную компьютером, и несколько десятков тысяч строк, что заставляет компилятор совершать магические действия. длинные вещи (предположительно, некоторый алгоритм O (N ^ 2)).
Это также может произойти, если у вас есть небольшая функция, которая затем по очереди вызывает множество мелких функций, которые, в конечном итоге, через слои встраивания превращаются в большой файл.
В других случаях я обнаружил, что сокращение количества файлов и помещение большего количества кода в один файл работает лучше.
В целом, мой опыт (как с моим собственным проектом компилятора, так и с компиляторами других людей / компании) заключается в том, что не разбор и чтение файлов занимают время, а различные этапы оптимизации и генерации кода. Вы можете попробовать это, скомпилировав все файлы, используя -fsyntax-only
или как там это называется для вашего компилятора. Это ПРОСТО прочитает источник и проверит его синтаксически правильно. Попробуйте также скомпилировать с -O0
если ты еще не Часто конкретный проход оптимизации является проблемой, а некоторые проходы хуже, чем другие, поэтому полезно проверить, какие отдельные проходы оптимизации существуют в конкретном -O
опция — в gcc, которая может быть указана с -Q -O2 --help=optimizers
[в этом случае для -O2
].
Вам действительно нужно выяснить, на что компилятор тратит время. Нет смысла менять код, если проблема в том, что вы проводите большую часть времени, оптимизируя код. Нет смысла сокращать оптимизаторы, если время потрачено на разбор, а оптимизация не добавляет дополнительного времени. Без фактического построения ВАШЕГО проекта очень сложно сказать наверняка.
Еще один совет, чтобы проверить top
чтобы увидеть, использует ли каждый ваш процесс компиляции 100% процессор — если нет, то, вероятно, у вас недостаточно памяти на вашем компьютере компиляции. У меня есть опция сборки для моего рабочего проекта, которая «убивает» мой настольный компьютер, выполняя так много памяти, что вся система просто останавливается — даже переключение с одной вкладки на другую в веб-браузере занимает 15-30 секунд. Единственное решение — меньше бегать -j
[но, конечно, я обычно забываю, и в этот момент — поэтому, если я не хочу прерывать это, я иду на обед, долгий перерыв на кофе или что-то подобное, пока он не закончится, потому что машина просто непригодна]. Это только для отладочных сборок, потому что сбор отладочной информации для большой базы кода занимает много памяти [очевидно!]