Этот вопрос, возможно, так или иначе нечетен, но как я могу ускорить g ++ время компиляции? Мой код C++ в большой степени использует повышение и шаблоны. Я уже переместился как можно больше из файлов заголовков, и используйте-j опцию, но тем не менее требуется долгое время для компиляции (и ссылка).
Есть ли какие-либо инструменты там, которые анализируют мой код и указывают на узкие места для компилятора? Или можно так или иначе представить компилятор, работающий на моем коде? Это было бы действительно хорошо, потому что иногда у меня есть впечатление, что я провел слишком много времени, уставившись на консольный журнал компилятора...
Что было для меня наиболее полезным:
-j3
глобально для make. Тем не менее, убедитесь, что ваши графики зависимостей в вашем Makefile верны, иначе у вас могут возникнуть проблемы. -O0
, если вы не тестируете скорость выполнения или размер кода (и ваш компьютер достаточно быстр, чтобы вас не волновало (возможно, небольшое) снижение производительности). Я предполагаю, что мы говорим о минутах для компиляции файла, то есть проблемы с предварительно скомпилированными заголовками или локальным диском не являются проблемой.
Длительное время компиляции с глубоким кодом шаблона (ускорение и т. Д.) Часто коренится в недружелюбном асимптотическом поведении gcc, когда дело доходит до создания экземпляров шаблона, в частности, когда вариативные шаблоны эмулируются с аргументами шаблона по умолчанию.
Вот документ, в котором сокращение времени компиляции названо мотивом для вариативных шаблонов:
cpptruths опубликовала статью о том, как gcc-4.5 намного лучше в этом отношении и тем, как он блестяще справляется со своими вариативными шаблонами:
IIRC, то у BOOST есть способ ограничить создание параметров шаблона по умолчанию для псевдовариадиков, я думаю, что 'g ++ -DBOOST_MPL_LIMIT_LIST_SIZE = 10' должно работать (по умолчанию 20)
UPDATE: Там также хороший поток с общими методами ускорения компиляции здесь на SO, который может быть полезен:
ОБНОВЛЕНИЕ: Это касается проблем с производительностью при компиляции шаблонов принятый ответ также рекомендует использовать gcc-4.5, также в качестве положительного примера упоминается clang:
Помимо того, что все добавили и что вы уже делаете (параллельная сборка, параметры компилятора и т. Д.), Рассмотрите возможность скрытия шаблонов в классах реализации, доступных через интерфейсы. Это означает, что вместо такого класса, как:
// ClsWithNoTemplates.h file, included everywhere
class ClsWithTemplates
{
ComplicatedTemplate<abc> member;
// ...
public:
void FunctionUsingYourMember();
};
, вы должны иметь:
// ClsWithNoTemplates.h file:
class ClsWithTemplatesImplementation; // forward declaration
// definition included in the ClsWithNoTemplates.cpp file
// this class will have a ComplicatedTemplate<abc> member, but it is only
// included in your ClsWithNoTemplates definition file (that is only included once)
class ClsWithNoTemplates
{
ClsWithTemplatesImplementation * impl; // no templates mentioned anywhere here
public:
void FunctionUsingYourMember(); // call impl->FunctionUsingYourMember() internally
};
Это немного изменяет ваш дизайн ООП, но это к лучшему: включение определения 'ClsWithNoTemplates' теперь быстро и вы только (предварительно) компилируете определение ClsWithNoTemplates один раз.
Кроме того, если вы измените код реализации, любой код, который включает ClsWithNoTemplates.h, вероятно, не потребуется переопределять.
Это изменение должно значительно увеличить ваше частичное время компиляции, а также поможет в случае, когда ваш ClsWithNoTemplates является общедоступным интерфейсом, экспортированным из файла библиотеки: поскольку файл не изменяется, когда вы меняете только реализацию, ваш зависимый клиент код вообще не нужно перекомпилировать.
Если вы много перекомпилируете, может помочь ccache . На самом деле это не ускоряет компиляцию, но даст вам кешированный результат, если по какой-то причине вы выполните бесполезную перекомпиляцию. Это может создать впечатление, что решается не та проблема, но иногда правила перестройки настолько сложны, что вы фактически заканчиваете тем же этапом компиляции во время новой сборки.
Дополнительная идея: если ваш код компилируется с clang , используйте его. Обычно это быстрее, чем gcc.
Вот что я сделал для ускорения сборки в очень похожем сценарии, который вы описываете (boost, templates, gcc)
Если файлов много, вы можете значительно ускорить компиляцию, имея только один файл .cpp, который # включает все остальные файлы .cpp. Это, конечно, требует, чтобы вы были более осторожны с макросами и такими, которые вы уже определили для каждого файла, поскольку теперь они будут видны другим файлам cpp.
Если файлов много, это может значительно сократить время компиляции.
Создавайте меньше шаблонов и встроенных функций. Предварительно скомпилируйте столько, сколько сможете, и просто свяжите это, а не компилируйте все с нуля. Убедитесь, что вы используете последнюю версию GCC.
Однако очевиден тот факт, что C ++ - невероятно сложный язык, и его компиляция занимает довольно много времени.
В данной работе описывается метод компиляции шаблонного кода подобно "традиционным" нешаблонным объектным файлам. Экономится время компиляции и компоновки, при этом на инстанцирование шаблона приходится всего одна строка кода.
Обычно наиболее дорогостоящими частями компиляции являются (а) чтение исходных файлов ( ВСЕ из них) и (б) загрузка компилятора в память для каждого исходного файла.
Если у вас есть 52 файла с исходным кодом (.cc), каждый из которых # включает 47 файлов #include (.h), вы собираетесь загрузить компилятор 52 раза и обработать 2496 файлов. В зависимости от плотности комментариев в файлах вы можете потратить значительную часть времени на поедание бесполезных символов. (В одной организации, которую я видел, файлы заголовков варьировались от 66% до 90% комментариев, при этом только от 10% до 33% файла были «значимыми». Единственное, что можно было сделать для повышения удобочитаемости этих файлов, - это удаление вычеркните каждый последний комментарий, оставив только код.)
Внимательно посмотрите, как ваша программа устроена физически. Посмотрите, можете ли вы объединить исходные файлы и упростить иерархию файлов #include.
Десятилетия назад такие компании, как IBM, понимали это и писали свои компиляторы так, чтобы компилятору можно было передать список файлов для компиляции, а не только один файл, и компилятор загружался бы только один раз.
Попробуйте метод PIMPL, этот вопрос: Какие методы можно использовать для ускорения времени компиляции C ++?
Это предотвратит отслеживание компилятором цепочки файлов заголовков и реализации каждый раз, когда вам нужно что-то сделать.