Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Precompiled headers


Автор: archimed7592 24.11.2007, 18:41
Цитата(Любитель @  24.11.2007,  18:31 Найти цитируемый пост)
Второе, вроде как, deprecated.

deprecated начиная с v4.0, просто вопрос был немного в другой плоскости, как, соответственно и ответ smile.

Цитата(Любитель @  24.11.2007,  18:31 Найти цитируемый пост)
На времени компиляции очень сказывается.

Почти не сказывается при использовании PCH smile.

Добавлено через 39 секунд
На всякий случай: PCH - это precompiled headers smile.

Автор: JackYF 24.11.2007, 21:18
Цитата(archimed7592 @  24.11.2007,  18:41 Найти цитируемый пост)
На всякий случай: PCH - это precompiled headers

 smile ну, я, например, precompiled headers не юзаю. Имхо, слишком много геморроя и неоднозначностей.

Цитата(Любитель @  24.11.2007,  18:31 Найти цитируемый пост)
На времени компиляции очень сказывается.

Так что +много, и + проект "чище".

Автор: archimed7592 24.11.2007, 21:24
Цитата(JackYF @  24.11.2007,  21:18 Найти цитируемый пост)
Имхо, слишком много геморроя и неоднозначностей.

К примеру? 0_о
Я знаю только одну с ними проблему(точнее баг, и тот, скорее всего, уже исправлен в более свежих версиях).

Автор: JackYF 24.11.2007, 23:08
Цитата(archimed7592 @  24.11.2007,  21:24 Найти цитируемый пост)
К примеру? 0_о

давно как-то раз связался. И потом наткнулся на очень странные сообщения компилятора - то файл он не находит, то ещё что-то. Уже не помню.
Бага, не бага, но пока я с ними связываться не хочу.
субъективная психологическая установка, если хотите


Автор: archimed7592 24.11.2007, 23:17

M
archimed7592
Сообщения разделены из темы [QT4] компилится но не работает


Добавлено через 3 минуты и 1 секунду
Цитата(JackYF @  24.11.2007,  23:08 Найти цитируемый пост)
давно как-то раз связался. И потом наткнулся на очень странные сообщения компилятора - то файл он не находит, то ещё что-то. Уже не помню.

Ммм... Просто для использования PCH есть несколько простых правил. При их соблюдении - ну, программировать, что ли приятней, когда build не занимает 2-3 минуты(у меня сейчас, к сожалению, очень слабенькая машина - бывает и по 5-7 минут :().

Автор: archimed7592 24.11.2007, 23:37

M
archimed7592
Тема перенесена из С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets

Автор: JackYF 24.11.2007, 23:42
Цитата(archimed7592 @  24.11.2007,  23:17 Найти цитируемый пост)
Просто для использования PCH есть несколько простых правил.

Ну, как нибудь на досуге надо будет ещё раз попробовать smile.


Автор: archimed7592 24.11.2007, 23:54
Цитата(JackYF @  24.11.2007,  23:42 Найти цитируемый пост)
Ну, как нибудь на досуге надо будет ещё раз попробовать smile.

Дам пару наводочек(в принципе, всё это можно прочитать в мануале GCC) smile.
1. В PCH суют уже готовые библиотеки(т.е. "рабочие" заголовки туда засовывать не нужно, ибо при их модификации будет происходит rebuild PCH, что, само по себе, операция достаточно долгая - сравнимо с минутой).
2. Может быть только один PCH.
2. include "PCH.hpp" должно идти первой строчкой(в идеале, ДО первого C/C++ token'а).
3. Компилировать PCH нужно с теми же define'ами и теми же опциями компилятора.

Вот, собственно и всё smile. Прилагаю архивчик с используемым мною PCH.

PS. Ах, да, чуть не забыл - у qmake есть прекрасная переменная: PRECOMPILED_HEADER(assistant тебе в помощь) smile.

Автор: bsa 25.11.2007, 00:57
Собрал свой проект с использованием pch:
real    1m12.063s
user    1m2.440s
sys     0m12.277s

И без использования:
real    1m49.846s
user    1m40.698s
sys     0m13.381s

Процентов 30% экономии времени. Правда, обнаружилась проблема с <boost/bind.hpp> (при линковке куча проблем с _1, _2...) и <boost/date_time/time.hpp> (при создании pch gcc 4.1.2 что-то не понравилось со скобкой в этом файле)

Автор: JackYF 25.11.2007, 01:01
Спасибо за инфу и вообще за обращение внимание на возможность использования PCH...

Но в архиве же почти все хедеры, которые могут в принципе когда-нибудь понадобиться, уже туда засунуты разом и скопом!... неужели компилятор это всё быстрее схавает, чем указанные конкретные хедеры в каждом конкретном проекте?

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


Автор: archimed7592 25.11.2007, 01:01
Цитата(bsa @  25.11.2007,  00:57 Найти цитируемый пост)
Процентов 30% экономии времени.

Хех. А ты попробуй теперь изменить один файл и опять сделать make ;).


Цитата(bsa @  25.11.2007,  00:57 Найти цитируемый пост)
Правда, обнаружилась проблема с <boost/bind.hpp> (при линковке куча проблем с _1, _2...)

Вот об этой проблеме я и говорил smile. Только у меня она проявлялась для boost::lambda::.., а с bind никаких проблем нет.
Баг, насколько я понимаю, в обработке gcc анонимных пространств имён. Значит в gcc-4 проблемы с pch тоже остались? А жаль :(.

Добавлено через 2 минуты и 49 секунд
Цитата(JackYF @  25.11.2007,  01:01 Найти цитируемый пост)
Но в архиве же почти все хедеры, которые могут в принципе когда-нибудь понадобиться, уже туда засунуты разом и скопом!... неужели компилятор это всё быстрее схавает, чем указанные конкретные хедеры в каждом конкретном проекте?

Фишка в том, что схавает он это один раз. В последующем компилировать сами модули будет также быстро, как и msvc(субъективная оценка).

Автор: bsa 25.11.2007, 01:15
Кстати, у меня gcc pch делал порядка 10 секунд для этого:
Код
#if defined __cplusplus

# include <QtGui>
# include <QApplication>

# include <algorithm>
# include <string>
# include <vector>
# include <list>
# include <set>
# include <map>

# include <iostream>
# include <iomanip>
# include <fstream>
# include <sstream>

# include <boost/spirit.hpp>
# include <boost/program_options.hpp>
# include <boost/thread.hpp>
# include <boost/utility.hpp>
# include <boost/signal.hpp>
# include <boost/format.hpp>
# include <boost/smart_ptr.hpp>
# include <boost/tuple/tuple.hpp>
# include <boost/lexical_cast.hpp>

#endif    //__cplusplus

Автор: archimed7592 25.11.2007, 01:19
bsa, по сути, без разницы - пусть хоть 2 минуты делает, если это делать придётся раз в месяц, то ничего страшного smile.

А вот, когда каждые 40 минут приходится по 5 минут ждать пока каждый модуль "родит" - вот это уже "страшно" smile.

Автор: bsa 25.11.2007, 01:24
У меня на слабых машинах другая проблема - 5 минут жду, пока слинкуется  smile 

Автор: archimed7592 25.11.2007, 01:28
К сожалению, prelinked headers пока не изобрели smile.

Правда, я помню долго ждал линковки только один раз, когда, в отладочных целях, поставил ключик -fkeep-inline-functions smile.

Автор: SaDFromSpb 25.11.2007, 02:26
Еще помогает ключик компилятора, который компиляцию распараллеливает (например, -j для gcc). Ну это совет для счастливых обладателей многоядерных систем (ну или хотя бы Р4 с HT). Вот у меня библиотека собиралась где-то полторы минуты, а когдя я про этот ключик узнал, стала за 10 секунд собираться, ибо в машине два четырехъядерных ксеона.
А еще компиляцию по сети распараллеливать можно....

Автор: archimed7592 25.11.2007, 02:35
SaDFromSpb, этот ключик имеет какой-нибудь смысл при компиляции одного модуля? Или только когда все модули скопом компилируешь помогает?
Просто, я точно такой же ключик использую, только относительно make - он одновременно запускает компиляцию сразу нескольких модулей(точнее использовал - сейчас p3-1GHz + 768RAM делать этого не позволяют :( ).

Автор: SaDFromSpb 25.11.2007, 03:17
Цитата(archimed7592 @  25.11.2007,  02:35 Найти цитируемый пост)
Просто, я точно такой же ключик использую, только относительно make - он одновременно запускает компиляцию сразу нескольких модулей(точнее использовал - сейчас p3-1GHz + 768RAM делать этого не позволяют :( ). 

А!! блин! Спать уже пора мне! Естественно, этот ключ к make'у относится! Распараллеливается по объектникам, на сколько я могу судить. Следовательно, при компиляции одного - смысла не имеет.

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

Автор: archimed7592 25.11.2007, 03:31
Цитата(SaDFromSpb @  25.11.2007,  03:17 Найти цитируемый пост)
Распараллеливается по объектникам, на сколько я могу судить

По make targets, если быть точнее smile.


Цитата(SaDFromSpb @  25.11.2007,  03:17 Найти цитируемый пост)
ПыСы: Знатный исходничек должен быть, чтобы единственный объектник из него значительное время компилился.

Не обязательно. В случае неиспользования PCH необходимо приличное время на парсинг хэдеров. Т.е. вот у меня, даже при размере одного модуля не более 250 строк, он без PCH компилится 15-40 секунд. Вот и посчитай сколько времени у меня идёт пересборка проектика из 50-60 модулей. C PCH 1-2 секунды на модуль. Разница совсем не 30% smile.

Автор: SaDFromSpb 25.11.2007, 04:05
Цитата(archimed7592 @  25.11.2007,  03:31 Найти цитируемый пост)

По make targets, если быть точнее smile.

Ага.  smile 

Цитата(archimed7592 @  25.11.2007,  03:31 Найти цитируемый пост)
Т.е. вот у меня, даже при размере одного модуля не более 250 строк, он без PCH компилится 15-40 секунд.

Хм.. Однако ж..  smile

Автор: Mayk 25.11.2007, 06:41
Цитата(archimed7592 @  25.11.2007,  05:01 Найти цитируемый пост)

Хех. А ты попробуй теперь изменить один файл и опять сделать make ;).

замеряем. [тесты  приложу в аттаче]
Цитата(./test_pch.sh)

precompiled headers only
w.o. pch: 0:02.60
pch: 0:00.24

разница ощутима.

Цитата(bsa @  25.11.2007,  04:57 Найти цитируемый пост)
Правда, обнаружилась проблема с <boost/bind.hpp> (при линковке куча проблем с _1, _2...) 

теперь пробуем с лямбдой и биндом, #include которых вынесен из pch.hh в *.cpp:
[мне было в ломы читать доку о том как заставить компилить .hpp в .gch и йа тупо переименовал файл]
Цитата(./test_pch2.sh)

precompiled headers + #include boost/lambda et al
w.o. pch: 0:03.32
pch: 0:00.75

ыыыы. 

Однако как-то неприятно что boost.bind, помещенный в pch.hpp приводит к ошибкам линковки. 
Вот допустим, изменили мы исходники, компилируем, линкуем, и тут оп-па. ошибки. 
Вот сиди как дурак и думай, это ты накосячил, или pch.

Цитата(archimed7592 @  25.11.2007,  05:28 Найти цитируемый пост)
К сожалению, prelinked headers пока не изобрели

Зато изобрели http://osdir.com/ml/kde.devel.cygwin/2005-01/msg00011.html smile 

Автор: Alek86 25.11.2007, 08:48
а я придерусь к
Цитата(archimed7592 @  24.11.2007,  23:54 Найти цитируемый пост)
2. Может быть только один PCH.

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


все это не мои идеи, а нагло спертые с книги "Шаблоны C++ Справочник разработчика" smile

Автор: bsa 25.11.2007, 12:23
Alek86, ограничение в один PCH накладывает qmake.

Добавлено через 3 минуты и 17 секунд
Цитата(archimed7592 @ 25.11.2007,  01:28)
Правда, я помню долго ждал линковки только один раз, когда, в отладочных целях, поставил ключик -fkeep-inline-functions smile.

У меня такого ключика нет. Но тормозит так дико именно на сборке проекта для отладки (хотя, релиз там собирать не пробовал).

Автор: archimed7592 25.11.2007, 13:41
Цитата(bsa @  25.11.2007,  12:23 Найти цитируемый пост)
Alek86, ограничение в один PCH накладывает qmake.

Не только smile.

Цитата(Alek86 @  25.11.2007,  08:48 Найти цитируемый пост)
PCH должно быть несколько (для больших проектов)

Видишь ли... Ты можешь насоздавать с десяток PCH, но если взять произвольный модуль, то в нём должен использоваться только один PCH. Это очень ясно прописано в мануале GCC(и ограничение qmake тут не при чём - более одного PCH не позволяет и MSVC).

Цитата(Mayk @  25.11.2007,  06:41 Найти цитируемый пост)
[мне было в ломы читать доку о том как заставить компилить .hpp в .gch и йа тупо переименовал файл]

Код
g++ -x c++-header [много ключиков компилятора] -o tmp/objs/PCH.hpp.gch/c++ ../src/PCH.hpp

Автор: Alek86 25.11.2007, 14:01
Цитата

One attractive approach to manage precompiled headers is to create layers of precompiled headers that go from the most widely used and stable headers (for example, our std.hpp header) to headers that aren't expected to change all the time and therefore are still worth precompiling. However, if headers are under heavy development, creating precompiled headers for them can take more time than what is saved by reusing them. A key concept to this approach is that a precompiled header for a more stable layer can be reused to improve the precompilation time of a less stable header.

цитата из "Cpp Templates The Complete Guide" глава 6.5

я неправильно прочел? тут другой смысл?

Автор: archimed7592 25.11.2007, 14:13
Цитата(Alek86 @  25.11.2007,  14:01 Найти цитируемый пост)
я неправильно прочел? тут другой смысл? 

Смысл тут такой, что делать слои из PCH.
Я же говорил о следующей ситуации: допустим, ты отдельно прекомпильнёшь std.hpp, отдельно Qt.hpp и напишешь в модуле
Код

#include "std.hpp"
#include "Qt.hpp"

Так вот, так делать нельзя - можно только что-то одно. Слоями можно(но смысла особого не вижу - разве что свои рабочие заголовки прекомпилять).

Автор: Alek86 25.11.2007, 14:17
Цитата(archimed7592 @  25.11.2007,  14:13 Найти цитируемый пост)
но смысла особого не вижу

я вижу для больших проектов. жаль, если нет возможности


Цитата(archimed7592 @  25.11.2007,  14:13 Найти цитируемый пост)
разве что свои рабочие заголовки прекомпилять

почему нельзя чужие? они ж тоже меняются (но намного реже) - их прекомпилять и надо

Автор: archimed7592 25.11.2007, 14:23
Цитата(Alek86 @  25.11.2007,  14:17 Найти цитируемый пост)
я вижу для больших проектов

Я не пробовал использовать "слоевую" организацию PCH - если при компиляции рабочих хэдеров действительно получится reuse'ить уже готовый PCH, содержащий std,Qt,Boost и пр. либы, которые, то это просто прекрасно(тогда понимаю, почему bsa сказал, что ограничение на один PCH - это у qmake).

Цитата(Alek86 @  25.11.2007,  14:17 Найти цитируемый пост)
почему нельзя чужие? они ж тоже меняются (но намного реже) - их прекомпилять и надо 

Да... не всегда намного реже smile. Зависит от политики делания commit'ов.

Автор: bsa 25.11.2007, 14:50
Я просто посмотрел, команду компиляции g++ с использованием PCH и без. Отличие только одно - добавляется -include debug/projectname.gch, где debug/projectname.gch - это такой каталог, в котором создается файл "c++", размером под сотню мегабайт. В описании опции -include в мане gcc сказано, что она аналогична инструкции препроцессора #include в тексте программы. Отсюда напрашивается вывод, что можно указывать больше директив компилятора -include для каждого набора заголовков... Но что-то мне подсказывает, что для одного модуля не стоит использовать более одного прекомпилированного заголовка.

Автор: archimed7592 25.11.2007, 15:04
Цитата(bsa @  25.11.2007,  14:50 Найти цитируемый пост)
Но что-то мне подсказывает, что для одного модуля не стоит использовать более одного прекомпилированного заголовка. 

http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html#Precompiled-Headers
Цитата
Only one precompiled header can be used in a particular compilation.

Там же ещё несколько правил, относительно корректного использования pch.

Автор: dix75 9.1.2010, 13:34
Цитата(archimed7592 @  24.11.2007,  23:54 Найти цитируемый пост)
2. include "PCH.hpp" должно идти первой строчкой(в идеале, ДО первого C/C++ token'а).

Не понял это где в хидере или реализации?

Автор: archimed7592 10.1.2010, 10:45
Цитата(dix75 @  9.1.2010,  13:34 Найти цитируемый пост)
Не понял это где в хидере или реализации?

В реализации.

Автор: bsa 11.1.2010, 01:45
в случае с gcc, на сколько я понял, делать #include "pch.hpp" совсем не обязательно. Если сделать, то хуже не будет (если "стражи" не забыты).

Автор: dix75 31.1.2010, 15:17
Цитата(bsa @  11.1.2010,  01:45 Найти цитируемый пост)
в случае с gcc, на сколько я понял, делать #include "pch.hpp" совсем не обязательно.

под windows да
под linux почему-то не работает(может ключики какие-то нужны?)

Автор: bsa 2.2.2010, 00:00
dix75, что именно не работает? не работает, когда нет #include  "pch.hpp"?

Автор: dix75 2.2.2010, 09:56
bsa
Я под виндой ничего не добавлял 
т.е. не добавлял #include  "pch.hpp" эту строчку в реализации
но под linux так неполучалось
Сейчас все заработало

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)