 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mario Schunda Guest
|
Posted: Tue Mar 28, 2006 11:06 pm Post subject: Groesse der exe bei Template C++ Programmen |
|
|
Hallo NG
Vielleicht ein wenig OT.
Ich habe hier ein Projekt mit sehr vielen Templates.
Dieses wird im MSVC und GCC Compiliert.
Am Anfang wahr der daraus erzeugte Code etwa gleich groß.
Je mehr das Projekt aber an größe gewinnt je mehr unterscheiden sich die
daraus erzeugten Codes. (Immer als Release gesehen zb: Inline, O2 usw. an)
Und zwar hat der GCC den Größten ... :-)
Der vom GCC erzeugte Code hat zur Zeit etwa 50% Prozent mehr Volumen. Kann
das den richtig sein?
Interessanterweise ist der Code ohne Inline und ohne Optimirung beim GCC
kleiner als der Release Code.
Was läuft da schief?
Kann es damit zusammen hängen das für jede Copilierte Datei eine Template
Objekt erzeugt wird und diese auch beim linken doppelt und dreifach im Code
zu finden sind? Irgendwas hatte ich da mal gelesen?
Hat jemand ein Tip oder Informationen dazu?
Hat das was mit dem -frepo zu tun?
Mario
PS: habe gerade Optimirung -Os (size) benutzt... huch von vorher 870 KB auf
ganze 640 KB. Jetzt liegt das ganze zum MSVC gar nicht mehr so weit
auseinander.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Marcel Müller Guest
|
Posted: Wed Mar 29, 2006 3:06 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Hallo,
Mario Schunda schrieb:
| Quote: | Kann es damit zusammen hängen das für jede Copilierte Datei eine Template
Objekt erzeugt wird und diese auch beim linken doppelt und dreifach im Code
zu finden sind? Irgendwas hatte ich da mal gelesen?
|
Ja, abhängig von der gcc-Version kann das sein.
| Quote: | Hat jemand ein Tip oder Informationen dazu?
|
Stichwort: Weak-Linker.
Marcel
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Wed Mar 29, 2006 5:06 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Mario Schunda wrote:
| Quote: | Hallo NG
Vielleicht ein wenig OT.
Ich habe hier ein Projekt mit sehr vielen Templates.
Dieses wird im MSVC und GCC Compiliert.
Am Anfang wahr der daraus erzeugte Code etwa gleich groß.
Je mehr das Projekt aber an größe gewinnt je mehr unterscheiden sich die
daraus erzeugten Codes. (Immer als Release gesehen zb: Inline, O2 usw. an)
Und zwar hat der GCC den Größten ...
|
Das zwei unterschiedliche Compiler unterschiedlich Großen Code erzeugt,
würde mich jetzt nicht wirklich wundern. Ich könnte mir vorstellen, das
debug-Informationen, wie z.B. Typenamen einen großen Teil des
Executables ausmacht.
mfg Torsten
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Wed Mar 29, 2006 6:06 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Mario Schunda wrote:
| Quote: | Ich habe hier ein Projekt mit sehr vielen Templates.
Dieses wird im MSVC und GCC Compiliert.
Am Anfang wahr der daraus erzeugte Code etwa gleich groß.
Je mehr das Projekt aber an größe gewinnt je mehr unterscheiden sich die
daraus erzeugten Codes. (Immer als Release gesehen zb: Inline, O2 usw. an)
Und zwar hat der GCC den Größten ... :-)
Der vom GCC erzeugte Code hat zur Zeit etwa 50% Prozent mehr Volumen. Kann
das den richtig sein?
|
Templates machen es besonders einfach, Bloat zu generieren. Schreibst du
template<typename T>
class foo {
/* hier alle Memberfunktionen inkl. Rumpf */
};
sind alle Members implizit inline, und diesem Wunsch folgt der gcc
selbstverständlich. Schreibst du
template<typename T>
class foo {
/* hier nur die Funktionsköpfe */
};
template<typename T> void foo<T>::member1()
{ /* Rumpf */ }
template<typename T> void foo<T>::member2()
{ /* Rumpf */ }
... usw ...
sind sie nicht mehr inline.
In dem Projekt, an dem ich beruflich arbeite, haben wir IIRC knapp ein
halbes MB Code gespart dadurch.
| Quote: | Kann es damit zusammen hängen das für jede Copilierte Datei eine Template
Objekt erzeugt wird und diese auch beim linken doppelt und dreifach im Code
zu finden sind? Irgendwas hatte ich da mal gelesen?
|
State-of-the-art ist eigentlich, dass genau das nicht mehr passiert.
Zumindest g++ mit ELF-Objektformat packt Templateinstanzen in
"linkonce"-Sektionen, so dass der Linker nur eine davon in die .exe packt.
| Quote: | Hat das was mit dem -frepo zu tun?
|
Ich weiß nicht, auf welchen Plattformen man -frepo benutzt, aber auf den
ELF-Plattformen braucht man's nicht.
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Thomas Rachel Guest
|
Posted: Wed Mar 29, 2006 10:56 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Mario Schunda wrote:
| Quote: | Interessanterweise ist der Code ohne Inline und ohne Optimirung beim GCC
kleiner als der Release Code.
|
Naja, daß der Code ohne Inline kompakter ist als mit inline, sollte klar
sein.
Funktionen zu inlinen bringt Geschwindigkeitsvorteile bei größerem Code. Je
größer die zu inlinenden Funktionen sind und je öfter sie verwendet werden,
umso größer wird dieser Effekt ausfallen.
| Quote: | PS: habe gerade Optimirung -Os (size) benutzt... huch von vorher 870 KB
auf ganze 640 KB. Jetzt liegt das ganze zum MSVC gar nicht mehr so weit
auseinander.
|
Das ist der gegenläufige Effekt - hier sparst Du Größe, bekommst aber u.U.
langsameren Code.
Thomas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Heinz Saathoff Guest
|
Posted: Thu Mar 30, 2006 8:06 am Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Moin,
Stefan Reuther schrieb...
| Quote: | Templates machen es besonders einfach, Bloat zu generieren. Schreibst du
template<typename T
class foo {
/* hier alle Memberfunktionen inkl. Rumpf */
};
sind alle Members implizit inline, und diesem Wunsch folgt der gcc
selbstverständlich.
|
Macht er das auch bei umfangreicheren Memberfunktionen? Mein Compiler
kann z.B. nur einfachere Getter/Setter wirklich inlinen. Sobald eine
Schleife vorkommt, wird die Funktion tatsächlich als Funktion generiert.
Bei Templates dann eben N-mal.
- Heinz
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Jakob Bieling Guest
|
Posted: Thu Mar 30, 2006 1:06 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Heinz Saathoff <newshsaat (AT) arcor (DOT) de> wrote:
| Quote: | Moin,
Stefan Reuther schrieb...
Templates machen es besonders einfach, Bloat zu generieren.
Schreibst du template<typename T
class foo {
/* hier alle Memberfunktionen inkl. Rumpf */
};
sind alle Members implizit inline, und diesem Wunsch folgt der gcc
selbstverständlich.
Macht er das auch bei umfangreicheren Memberfunktionen? Mein Compiler
kann z.B. nur einfachere Getter/Setter wirklich inlinen. Sobald eine
Schleife vorkommt, wird die Funktion tatsächlich als Funktion
generiert. Bei Templates dann eben N-mal.
|
N-mal? Du meinst mit N jetz aber nicht die Schleifendurchlaeufe
oder? Wenn doch, versteh ich aber nicht, wie du dann N
Template-Instanzen bekommen kannst.
regards
--
jb
(reply address in rot13, unscramble first)
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Peter Gertner Guest
|
Posted: Thu Mar 30, 2006 1:06 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Thomas Rachel schrieb:
| Quote: | Funktionen zu inlinen bringt Geschwindigkeitsvorteile bei größerem Code.
Ich dachte immer es wäre genau umgekehrt?! |
Bei größerem Code ist das Verhältnis zwischen Laufzeit der
Parameterübergabe und des CALLs/RETs und der Laufzeit des Codes kleiner.
Wenn ich nur eine einzige Integer-Operation hat, wird die wohl deutlich
schneller sein als zwei Zahlen auf den Stack zu legen, zu CALLen und
anschließend wieder zu RETen (inklusive den alten Krempel vom Stack
entfernen). Umgekehrt, wenn ich eine >50-Zeilen-Funktion mit
Dateioperationen, Sortierung und überhaupt habe, dann fällt der Aufruf
als Funktion kaum noch großartig auf.
Umgekehrt können doch aber mehr Cache (und/oder Page) Misses entstehen,
wenn ich große Funktionen inline und deswegen mein Binary die Größe
eines Wales erreicht, was wiederum Performance kostet, unter Umständen
mehr als ich durch das Sparen des Aufrufs als Funktion spare.
Oder habe ich da was falsches gelernt?
Bis später
Peter
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Stefan Reuther Guest
|
Posted: Thu Mar 30, 2006 5:06 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Heinz Saathoff wrote:
| Quote: | Stefan Reuther schrieb...
Templates machen es besonders einfach, Bloat zu generieren. Schreibst du
template<typename T
class foo {
/* hier alle Memberfunktionen inkl. Rumpf */
};
sind alle Members implizit inline, und diesem Wunsch folgt der gcc
selbstverständlich.
Macht er das auch bei umfangreicheren Memberfunktionen? Mein Compiler
kann z.B. nur einfachere Getter/Setter wirklich inlinen. Sobald eine
Schleife vorkommt, wird die Funktion tatsächlich als Funktion generiert.
|
Ja. Schleifen sind für den gcc offenbar kein Hinderungsgrund. Jedenfalls
inlined der gcc oft und gern auch Funktionen, die aus mehreren Hundert
Maschineninstruktionen bestehen. Da muss man etwas vorsichtiger sein mit
der inline-Deklaration.
Stefan
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Thomas Rachel Guest
|
Posted: Thu Mar 30, 2006 7:31 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Peter Gertner wrote:
| Quote: | Thomas Rachel schrieb:
Funktionen zu inlinen bringt Geschwindigkeitsvorteile bei größerem Code.
Ich dachte immer es wäre genau umgekehrt?!
|
Ich habe mich mal wieder mißverständlich ausgedrückt.
Ich meinte:
Funktionen zu inlinen bringt Geschwindigkeitsvorteile, beschert Dir jedoch
(u. U.) größeren Code. (Du bringst unten selbst ein Gegenbeispiel - eine
einzige Operation wird geinlined evtl. sogar kleiner sein.)
| Quote: | Bei größerem Code ist das Verhältnis zwischen Laufzeit der
Parameterübergabe und des CALLs/RETs und der Laufzeit des Codes kleiner.
|
Das auf jeden Fall - je länger der Code braucht, umso weniger fällt CALL/RET
ins Gewicht. Mit der Größe des Codes hat das nur sekundär zu tun - kurze
Schleifen mit hohen Count-Werten laufen länger als Code, der doppelt so
groß ist, aber nur 1x durchlaufen wird.
| Quote: | Wenn ich nur eine einzige Integer-Operation hat, wird die wohl deutlich
schneller sein als zwei Zahlen auf den Stack zu legen, zu CALLen und
anschließend wieder zu RETen (inklusive den alten Krempel vom Stack
entfernen).
|
Das ist klar.
| Quote: | Umgekehrt, wenn ich eine >50-Zeilen-Funktion mit
Dateioperationen, Sortierung und überhaupt habe, dann fällt der Aufruf
als Funktion kaum noch großartig auf.
|
Das auch - es ist bei so großen Funktionen daher idR nicht sinnvoll, sie zu
inlinen.
| Quote: | Umgekehrt können doch aber mehr Cache (und/oder Page) Misses entstehen,
wenn ich große Funktionen inline und deswegen mein Binary die Größe
eines Wales erreicht, was wiederum Performance kostet, unter Umständen
mehr als ich durch das Sparen des Aufrufs als Funktion spare.
|
Auch richtig.
Aber denke mal an "Mitteldinger" zwischen sehr kurz und sehr lang:
beispielsweise Arrayzugriffe, bei denen vorher eine Bereichsprüfung
durchgeführt wird, oder Integeroperationen, die bei Verlassen des
Wertebereiches Sättigung statt Overflow zeigen sollen (will sagen: bei
16bit signed 16384+26384 soll nicht -22768, sondern +32767 herauskommen).
Solche Operationen resultieren meist in Code, der größer ist als ein
Funktionsaufruf, dieser jedoch bei entsprechend häufigem Aufruf einen
erheblichen Overhead mit sich bringt.
Thomas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Heinz Saathoff Guest
|
Posted: Thu Mar 30, 2006 8:11 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
MOin,
Jakob Bieling schrieb...
| Quote: | Macht er das auch bei umfangreicheren Memberfunktionen? Mein Compiler
kann z.B. nur einfachere Getter/Setter wirklich inlinen. Sobald eine
Schleife vorkommt, wird die Funktion tatsächlich als Funktion
generiert. Bei Templates dann eben N-mal.
N-mal? Du meinst mit N jetz aber nicht die Schleifendurchlaeufe
oder?
|
Was ich meinte ist, dass eine inline Funktion, die im Rumpf eine
Schleife enthält, nicht ge-inlined wird, sondern als externe Funktion
generiert wird.
| Quote: | Wenn doch, versteh ich aber nicht, wie du dann N
Template-Instanzen bekommen kannst.
|
Die N-Instanzen bekomme ich, weil ich N-templates instantiiere, wodurch
die nicht inline-baren Funktionen eben auch N-mal generiert werden.
Das kann die Programmgröße im Gegensatz zum Inlining sogar reduzieren,
vor allem dann, wenn so eine Funktion mehr als einmal an verschiedenen
Stellen aufgerufen wird.
- Heinz
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Jakob Bieling Guest
|
Posted: Fri Mar 31, 2006 12:36 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Heinz Saathoff <newshsaat (AT) arcor (DOT) de> wrote:
| Quote: | Jakob Bieling schrieb...
Macht er das auch bei umfangreicheren Memberfunktionen? Mein
Compiler kann z.B. nur einfachere Getter/Setter wirklich inlinen.
Sobald eine Schleife vorkommt, wird die Funktion tatsächlich als
Funktion generiert. Bei Templates dann eben N-mal.
N-mal? Du meinst mit N jetz aber nicht die Schleifendurchlaeufe
oder?
Was ich meinte ist, dass eine inline Funktion, die im Rumpf eine
Schleife enthält, nicht ge-inlined wird, sondern als externe Funktion
generiert wird.
Wenn doch, versteh ich aber nicht, wie du dann N
Template-Instanzen bekommen kannst.
Die N-Instanzen bekomme ich, weil ich N-templates instantiiere,
wodurch die nicht inline-baren Funktionen eben auch N-mal generiert
werden. Das kann die Programmgröße im Gegensatz zum Inlining sogar
reduzieren, vor allem dann, wenn so eine Funktion mehr als einmal an
verschiedenen Stellen aufgerufen wird.
|
Ah, ich habs jetzt verstanden, denke ich. Allerdings stimme ich dir
da nicht zu. Eine Member-Funktion einer Template-Klasse wird nur dann
kompiliert (und somit erzeugt sie auch nur dann Code), wenn sie benutzt
wird. Benutzt du diese Member-Funktion, haettest du sie mit oder ohne
Templates gebraucht. Mit anderen Worten, Templates machen deinen Code
nicht groesser als er haette ohnehin sein muesen.
regards
--
jb
(reply address in rot13, unscramble first)
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Peter Gertner Guest
|
Posted: Fri Mar 31, 2006 5:43 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
Thomas Rachel schrieb:
| Quote: | Ich meinte:
Funktionen zu inlinen bringt Geschwindigkeitsvorteile, beschert Dir jedoch
(u. U.) größeren Code.
Ah, okay. Ich dachte, "größerer Code" bezog sich auf den, der geinlined |
werden soll.
| Quote: | Aber denke mal an "Mitteldinger" [...]
Solche Operationen resultieren meist in Code, der größer ist als ein
Funktionsaufruf, dieser jedoch bei entsprechend häufigem Aufruf einen
erheblichen Overhead mit sich bringt.
Jupp. Sowas rückt man dann mit einem Profiler zu Leibe  |
Bis später
Peter
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Thomas Mang Guest
|
Posted: Fri Mar 31, 2006 7:06 pm Post subject: Re: Groesse der exe bei Template C++ Programmen |
|
|
"Jakob Bieling" <argfhesNGtzkQBGarg (AT) rot13 (DOT) com> schrieb im Newsbeitrag
news:e0im74$ham$03$1 (AT) news (DOT) t-online.com...
| Quote: | Heinz Saathoff <newshsaat (AT) arcor (DOT) de> wrote:
Jakob Bieling schrieb...
Macht er das auch bei umfangreicheren Memberfunktionen? Mein
Compiler kann z.B. nur einfachere Getter/Setter wirklich inlinen.
Sobald eine Schleife vorkommt, wird die Funktion tatsächlich als
Funktion generiert. Bei Templates dann eben N-mal.
N-mal? Du meinst mit N jetz aber nicht die Schleifendurchlaeufe
oder?
Was ich meinte ist, dass eine inline Funktion, die im Rumpf eine
Schleife enthält, nicht ge-inlined wird, sondern als externe Funktion
generiert wird.
Wenn doch, versteh ich aber nicht, wie du dann N
Template-Instanzen bekommen kannst.
Die N-Instanzen bekomme ich, weil ich N-templates instantiiere,
wodurch die nicht inline-baren Funktionen eben auch N-mal generiert
werden. Das kann die Programmgröße im Gegensatz zum Inlining sogar
reduzieren, vor allem dann, wenn so eine Funktion mehr als einmal an
verschiedenen Stellen aufgerufen wird.
Ah, ich habs jetzt verstanden, denke ich. Allerdings stimme ich dir da
nicht zu. Eine Member-Funktion einer Template-Klasse wird nur dann
kompiliert (und somit erzeugt sie auch nur dann Code), wenn sie benutzt
wird. Benutzt du diese Member-Funktion, haettest du sie mit oder ohne
Templates gebraucht. Mit anderen Worten, Templates machen deinen Code
nicht groesser als er haette ohnehin sein muesen.
|
Stimmt, nur kann mit templates die Klassenzahl mal "leicht explodieren".
Angenommen Du schreibst Deine eigene Containerklasse (wie std::vector), aber
als nicht-template. Dann ist der Typ der verwalteten Objekte vielleicht ein
Zeiger auf MeineBasisklasseFuerAlles oder so, und jede member function kommt
nur einmal vor.
Nun ist es ein template, und wird mit z.b. 200 verschiedenen Typen
instanziiert. Macht 200 unabh. Klassen, mit 200 voneinander unabh. member
functions. Es ist ja gerade der Sinn von templates, nur als Schablone zu
agieren (Wort !), um dann schnell daraus eigenständige Klassen machen zu
können. Und damit explodiert die Klassenzahl.
Ausserdem denke an function templates , z.b:
class NoTemplate
{
template <class T>
T aMember(T);
};
Hier findet template-argument-deduction gemäß Argument statt, also wird für
jeden Typ als Argument eine eigene Funktion generiert:
NoTemplate a;
a.aMember(12);
a.aMember(SomeContainer.size());
a.aMember(MyString[0]);
a.aMember( Pi * 2.0 * radius());
Das resultiert wahrscheinlich in 4, mindestens in 2 versch. Funktionen -
ohne dass es "besonders auffällig" ist.
Thomas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|