[c++] include 'boom' analyseren?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Ik werk nu aan een project waarbij heel vaak geldt dat als je een header file aanpast, je weer een kwartier zit te wachten op een bijna volledige rebuild. Daar wil ik graag wat aan doen. Simpele oplossingen genoeg, bijvoorbeeld: als je een class nodig hebt als argument-type is 'class X' beter voor dat geval dan '#include "X.h" '.

Wat ik daarvoor graag zou zien is de 'boom' van includes: welke header wordt indirect door het hele programma included, en waar moet ik bovenstaande (of een andere) truc toepassen om de bouw-tijden te verbeteren. Wie kent daar goede tools voor? We bouwen nu met CMake, als dat helpt.

Ik snap dat veel mensen denken dat dit geen goed idee is: als je een type nodig hebt moet je toch dat type includen, geen gezeur? Dat is normaal ook mijn eerste gedachte. Tweede gedachte is uiteraard dat de bouw-tijden verbeterd moeten worden. Daar ben ik het ook helemaal mee eens, maar bij een project van 26MB sourcecode zal dat waarschijnlijk wat meer tijd kosten ;) Daarnaast heeft include volgens mij het effect dat de CPP-file voor de compiler effectief langer is, dus verwacht ik dat als ik de include-boom kleiner maak, de compile-tijd ook korter wordt.

[ Voor 11% gewijzigd door MBV op 11-06-2015 12:55 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

We bouwen nu met CMake, als dat helpt.
Het helpt meer als je zegt welke compiler je gebruikt ;)
MSVC++ heeft /showIncludes
MBV schreef op donderdag 11 juni 2015 @ 12:52:
Ik snap dat veel mensen denken dat dit geen goed idee is: als je een type nodig hebt moet je toch dat type includen, geen gezeur? Dat is normaal ook mijn eerste gedachte.
FWIW, mijn eerste gedachte is dat iedereen zo weinig mogelijk moet includen, maar er niet vanuit moet gaan dat een andere header die jij include vast wel include wat jij verder nog nodig hebt.

Wat betreft build times, ik zit momenteel op een project met 73MB aan source code, maar een full rebuild duurt bij ons slechts een paar minuten. Hier wat tips:
[list]• Zo min mogelijk header dependencies. Daar ben je nu dus mee bezig :P
• Gebruik precompiled headers voor alle OS/std headers en evt veelgebruikte headers van je project zelf.
• Compile losse sourcefiles die veel onderlinge interactie hebben in een enkele stap door al die .cpp's in een andere .cpp te includen. Hierdoor hoeven relevante headers maar 1x geparsed te worden ipv voor elke sourcefile opnieuw, en reduceer je de linktijd omdat veel references @ compiletime al geresolved kunnen worden. Je iteratietijd voor simpele changes wordt wel iets langer, maar de winst bij het aanpassen van veelgebruikte headers is echt gigantisch.
• Gebruik een distributed build systeem zoals Incredibuild!!!

[ Voor 106% gewijzigd door .oisyn op 11-06-2015 13:20 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Check ook Header Hero een tool die je de "worst offenders" zou moeten geven :). Verder is natuurlijk de regel, include zo min mogelijk in header files :)

[ Voor 18% gewijzigd door PrisonerOfPain op 11-06-2015 13:29 ]


Acties:
  • 0 Henk 'm!

  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 20-09 23:24

BoAC

Memento mori

En forward declarations van classes in plaats van headers includen wil ook nog wel eens helpen :)

Acties:
  • 0 Henk 'm!

  • Brent
  • Registratie: September 2001
  • Laatst online: 19-09 10:55
Je moet zeker niet meer includen dan nodig, maar een partial rebuild van een project van <50mb source zou niet zo lang moeten duren. Ik werk ook aan een project van enkele tientalen megabytes en Cmake, en ik zou het een aardig bord include-spagetti noemen ;), maar kleine edits recompilen duurt 10 seconden max.

Humanist | Kernpower! | Determinist | Verken uw geest | Politiek dakloos


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Zet je sources op een SSD, instant speedness.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
farlane schreef op donderdag 11 juni 2015 @ 14:17:
Zet je sources op een SSD, instant speedness.
Dat zal vast een factor 2 snellere compiletime opleveren, dus in plaats van 15 minuten nu nog maar 8 minuten. Ik wil graag dat als ik alleen maar een argument aan een private functie van 1 class, en de calls daarbij, dat hij dan in 1 seconde klaar is, daar gaat geen hardware bij helpen ;)
.oisyn schreef op donderdag 11 juni 2015 @ 13:09:
[...]

Het helpt meer als je zegt welke compiler je gebruikt ;)
MSVC++ heeft /showIncludes
We maken een OSX-build met GCC en Windows-build met MSVC++. Ik zal eens kijken of de antieke versie die wij gebruiken al /showincludes ondersteunt, bedankt!
[list]
• Gebruik precompiled headers voor alle OS/std headers en evt veelgebruikte headers van je project zelf.
Zou ik eens moeten uitzoeken, bedankt voor de tip :)
• Compile losse sourcefiles die veel onderlinge interactie hebben in een enkele stap door al die .cpp's in een andere .cpp te includen. Hierdoor hoeven relevante headers maar 1x geparsed te worden ipv voor elke sourcefile opnieuw, en reduceer je de linktijd omdat veel references @ compiletime al geresolved kunnen worden. Je iteratietijd voor simpele changes wordt wel iets langer, maar de winst bij het aanpassen van veelgebruikte headers is echt gigantisch.
Ik denk dat daarvoor weinig kandidaten zijn, en ik wil niet dat minder compile-tijd voor meer onderhouds-moeilijkheid zorgt.
[quote]
• Gebruik een distributed build systeem zoals Incredibuild!!!
[/quote]
Dat was bij een vorige opdracht niet zo'n incredible verbetering ;) Goed idee, maar ik denk dat ik 350 euro per machine voorlopig niet uitgelegd krijg.
PrisonerOfPain schreef op donderdag 11 juni 2015 @ 13:28:
Check ook Header Hero een tool die je de "worst offenders" zou moeten geven :). Verder is natuurlijk de regel, include zo min mogelijk in header files :)
Bedankt voor de tip, ik zal er eens naar kijken :) Leuke detail van je tip: waarschijnlijk zorgt het verminderen van de includes in headers ervoor dat de include-lijst in cpp's langer wordt :P
BoAC schreef op donderdag 11 juni 2015 @ 13:37:
En forward declarations van classes in plaats van headers includen wil ook nog wel eens helpen :)
Zoals in de startpost staat? :)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

MBV schreef op donderdag 11 juni 2015 @ 16:32:
Leuke detail van je tip: waarschijnlijk zorgt het verminderen van de includes in headers ervoor dat de include-lijst in cpp's langer wordt :P
Maar feitelijk doet dat er weinig toe, want je betaalt hoe dan ook de prijs voor de include, of die nou vanuit een header wordt geïnclude of vanuit een source file.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
.oisyn schreef op donderdag 11 juni 2015 @ 16:39:
[...]

Maar feitelijk doet dat er weinig toe, want je betaalt hoe dan ook de prijs voor de include, of die nou vanuit een header wordt geïnclude of vanuit een source file.
Dat hangt er vanaf hoe het gebruikt word - als je header iets include wat 't in princiepe met een forward declaration af kan handelen en die header word all over the place geinclude terwijl je de andere header niet altijd nodig hebt (volg je 'm nog) dan kun je daar prima winst uit halen.

Maar hoe dan ook, minder includes is beter, maar ik heb ze liever in de compilation unit :)
MBV schreef op donderdag 11 juni 2015 @ 16:32:
[...]

Dat zal vast een factor 2 snellere compiletime opleveren, dus in plaats van 15 minuten nu nog maar 8 minuten. Ik wil graag dat als ik alleen maar een argument aan een private functie van 1 class, en de calls daarbij, dat hij dan in 1 seconde klaar is, daar gaat geen hardware bij helpen ;)
Dat is een behoorlijke winst anders :). Verder hebben wij onze solution ook opgesplits in ~100 dlls voor development die je incrementeel kunt builden. Een enkele dll build duurt 10 seconden terwijl de hele codebase ~15 minuten duurt. Dat is een prima workflow zolang je alleen code in die bepaalde dll aanpast.

[ Voor 35% gewijzigd door PrisonerOfPain op 11-06-2015 16:44 ]


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
.oisyn schreef op donderdag 11 juni 2015 @ 16:39:
[...]

Maar feitelijk doet dat er weinig toe, want je betaalt hoe dan ook de prijs voor de include, of die nou vanuit een header wordt geïnclude of vanuit een source file.
Compile-tijd-technisch etc heb je helemaal gelijk. Het nadeel is dat als je class X al gebruikt, en X.whatever(Y) wilt gebruiken, je de include van Y ook toe moet voegen in je CPP. Dat kan als developer soms een beetje irritant zijn.

Wat hij zei vond ik grappig, omdat een kortere lijst includes best wel voor een langere lijst elders kan zorgen :)

Acties:
  • 0 Henk 'm!

  • Foeijonghaai
  • Registratie: Juli 2001
  • Laatst online: 17-09 12:16
farlane schreef op donderdag 11 juni 2015 @ 14:17:
Zet je sources op een SSD, instant speedness.
I/O zal het probleem niet zijn. Een dataset van 26MB zal vast wel gecached worden.

Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 21-09 10:43

Matis

Rubber Rocket

Je zou kunnen kijken of de -pipe flag snelheidswinst zou kunnen bieden bij GCC. Hierdoor worden de object files niet wegggeschreven naar disk, maar in het geheugen bewaard.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Foeijonghaai schreef op donderdag 11 juni 2015 @ 20:08:
[...]

I/O zal het probleem niet zijn. Een dataset van 26MB zal vast wel gecached worden.
Mijn ervaring is dat het een wereld van verschil maakt : vergeet niet dat er tussendoor o.a. een berg object files gegenereerd worden.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • acemoo
  • Registratie: Maart 2006
  • Laatst online: 22:16
hoe zit dat met include guards/pragma once eigenlijk? Ik dacht dat die er voor zorgden dat een header file maar 1x verwerkt word? Als ik dit topic zo lees denk ik dat ze niet werken zoals ik verwacht dat ze werken.

Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Dat is 1x per .cpp file, dus met 1000 .cpp files is dat alsnog best wel vaak.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
MBV schreef op donderdag 11 juni 2015 @ 16:46:
[...]
Compile-tijd-technisch etc heb je helemaal gelijk. Het nadeel is dat als je class X al gebruikt, en X.whatever(Y) wilt gebruiken, je de include van Y ook toe moet voegen in je CPP. Dat kan als developer soms een beetje irritant zijn.
Nee, dat klopt niet helemaal.

Er zijn twee mogelijkheden: "X::whatever(Y y)" versus "X::whatever(Y& y)". In het laatste geval hoef je als gebruiker van X geen include toe te voegen. In het eerste geval heb je Y::Y(Yconst&) (de copy ctor) nodig, vandaar dat je dan wel de include van Y nodig hebt.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
.oisyn schreef op donderdag 11 juni 2015 @ 13:09:
[...]
Het helpt meer als je zegt welke compiler je gebruikt ;)
MSVC++ heeft /showIncludes
gcc heeft -M. En het incredibuild alternatief voor Linux is "distcc".

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
/showIncludes laat per bestand zien wat er geinclude wordt, is niet helemaal wat ik zoek. HeaderHero werkt best goed, dus bedankt voor die tip :) Helaas is daarbij geen onderscheid tussen STL includes als pak-em-beet sstream en includes van eigen files. Dat zo ongeveer elke CPP file sstream include geloof ik wel ;) En dat er heel veel qt-files heel veel geinclude worden ook.

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
MBV schreef op vrijdag 12 juni 2015 @ 11:15:
/showIncludes laat per bestand zien wat er geinclude wordt, is niet helemaal wat ik zoek. HeaderHero werkt best goed, dus bedankt voor die tip :) Helaas is daarbij geen onderscheid tussen STL includes als pak-em-beet sstream en includes van eigen files. Dat zo ongeveer elke CPP file sstream include geloof ik wel ;) En dat er heel veel qt-files heel veel geinclude worden ook.
stl & qt tellen ook gewoon mee met je compile tijd ;)

Acties:
  • 0 Henk 'm!

  • Foeijonghaai
  • Registratie: Juli 2001
  • Laatst online: 17-09 12:16
farlane schreef op vrijdag 12 juni 2015 @ 09:15:
Mijn ervaring is dat het een wereld van verschil maakt : vergeet niet dat er tussendoor o.a. een berg object files gegenereerd worden.
Ook die zouden prima in het cache moeten passen. Zo nee, dan zou ik meer RAM aanraden en daarna pas een SSD.

Een SSD zal zeker voordelen hebben bij bijv. de eerste keer laden van allerlei libraries en tooling zoals de compiler en de rest van je ontwikkelomgeving. Maar daarna is het maar een hele kleine set van kleine bestanden die steeds verandert en dan gaat een SSD je nauwelijks helpen.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Foeijonghaai schreef op zondag 14 juni 2015 @ 11:12:
Maar daarna is het maar een hele kleine set van kleine bestanden die steeds verandert en dan gaat een SSD je nauwelijks helpen.
1 header (die aangepast wordt) geinclude in 100 bestanden resulteert in 100 nieuwe object files, dat is ook zo'n beetje de crux van dit topic.
Wij hebben normaal gesproken niet extreem grote projecten, maar er waren mensen bij ons die vanaf netwerk schijven werkten : die deden er bij een build toch echt een stuk langer over dan ik op m'n ssd.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Netwerken zijn ook berucht ongelukkig voor builds. Combinatie van latency en cache problematiek.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
PrisonerOfPain schreef op vrijdag 12 juni 2015 @ 11:21:
[...]


stl & qt tellen ook gewoon mee met je compile tijd ;)
Dat is helemaal waar. Maar dat map.h, vector.h en set.h alledrie hetzelfde bestand includen wil ik niks aan veranderen, en dat dat het bestand is dat het meeste wordt geinclude kan ik weinig aan veranderen ;)

En misschien ga ik ervoor zorgen dat je ongelijk krijgt: QT en STL mag best precompiled worden, en dan kost QWhatever.h een stuk minder compiletijd dan MyWhatever.h :P
Pagina: 1