g++ - Optimierung-Flags: -fuse-linker-plugin vs -fwhole-program
Ich lese:
http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
Es als erstes vorgeschlagen:
In Kombination mit -flto
mit dieser option (-fwhole-program
) sollten nicht verwendet werden. Statt sich auf ein linker-plugin sollte sicherer und präziser Informationen.
Und dann schlägt es vor:
Wenn das Programm erfordert keine Symbole exportiert werden, ist es möglich, zu kombinieren -flto
und -fwhole-program
zu ermöglichen, die interprozedurale Optimierung, um mehr aggressive Annahmen, die sich möglicherweise führen zu einer Verbesserung der Möglichkeiten zur Optimierung. Verwendung von -fwhole-program
ist nicht notwendig, wenn der linker-plugin aktiv ist (siehe -fuse-linker-plugin
).
Heißt es, dass in der Theorie, mit -fuse-linker-plugin
mit -flto
bekommt immer eine optimierte ausführbare Datei als mit -fwhole-program
mit -flto
?
Habe ich versucht zu verwenden ld
link mit -fuse-linker-plugin
und -fwhole-program
getrennt, und die ausführbaren Dateien' Größen sind zumindest anders.
P. S. ich bin mit gcc 4.6.2 und ld 2.21.53.0.1 auf CentOS 6.
- fwiw, nach deinem Zitat - "Option-fwhole-program ist nicht notwendig, wenn der linker-plugin aktiv ist (siehe -fuse-linker-plugin)." - wir später sehen werden, die in der Dokumentation - "die option [
-fuse-linker-plugin
] ist standardmäßig aktiviert, wenn LTO-Unterstützung des GCC aktiviert ist, und GCC wurde konfiguriert für die Verwendung mit linker Unterstützung von plugins (GNU ld 2.21 oder höher oder gold)." - so würde ich vermuten, dass deckt die meisten vernünftigen modernen Installationen, die von gcc. das heißt, Sie haben eine default-option, die macht-fwhole-program
unnötig. aber das ist nur meine interpretation des ganzen!
Du musst angemeldet sein, um einen Kommentar abzugeben.
UPDATE: Siehe @PeterCordes Kommentar unten. Im wesentlichen -fuse-linker-plugin ist nicht mehr notwendig.
Diese Unterschiede sind subtil. Zuerst verstehen, was -flto tatsächlich tut. Es ist im wesentlichen erstellt eine Ausgabe, die optimiert werden können später (bei "link-time").
Was -fwhole-program tut, wird davon ausgegangen,", dass die aktuellen compilation unit stellt das gesamte Programm kompiliert werden" oder nicht, ob das tatsächlich der Fall ist. Daher, GCC davon aus, dass er weiß alle Orte, die eine bestimmte Funktion aufrufen. Als er sagt, es möglicherweise mehr aggressive inter-procedural-Optimierer. Ich werde erklären, dass in einem bit.
Schließlich, was -fuse-linker-plugin tut, ist tatsächlich die Optimierungen zur link-Zeit, die normalerweise getan werden, wie jede compilation unit durchgeführt wird. Also, das ist entworfen, um paar mit -flto weil -flto bedeutet, sparen Sie genug Informationen für Optimierungen später und -fuse-linker-plugin bedeutet eigentlich diese Optimierungen.
So, wo unterscheiden Sie sich? Naja, wie GCC-doc schon sagt, gibt es keinen Vorteil, im Prinzip mit -fwhole-program denn, die option geht davon aus, etwas, was Sie dann haben, um sicherzustellen, ist wahr. Um Sie zu brechen, definieren Sie einfach eine Funktion in einem .cpp-Datei, und verwenden Sie es in einem anderen. Sie erhalten einen linker-Fehler.
Ist es von Vorteil, zu -fwhole-program? Gut, wenn man nur eine kompiliereinheit, dann können Sie es verwenden, aber ehrlich gesagt, es wird nicht besser werden. Ich war in der Lage, verschiedene Größe ausführbaren Dateien mithilfe gleichwertige Programme, aber bei der überprüfung der tatsächlich generierte Maschinencode, Sie waren identisch. In der Tat, die einzigen Unterschiede, die ich sah, waren, dass die Zeilennummern mit debugging-Informationen waren unterschiedlich.
gcc -O3 -march=native ... -flto
Funktioniert Einfach in diesen Tagen, und hat alle notwendigen linker-plugin-Zeug. (Übergeben Sie die gleichen Optimierungs-Optionen, um die link-Befehl als wenn Sie kompiliert.)gcc -O2 -march=native ... -flto
auch tut? Viele Male, vor allem für Programme, die den Computer-code auf dem heißen Pfade größer als die trace-cache,O2
übertrifftO3
undO3
ist am besten angewendet, um die Funktionen auswählen. Und, vielen Dank für das update!-O2
auch "einfach nur funktioniert" natürlich. Aber nur-O3
ermöglicht die automatische Vektorisierung. Wenn alle wichtigen loops profitieren von auto-Vektorisierung ist es in der Regel lohnt sich die code-Größe Kosten. Moderne x86 CPUs nicht mit einem trace-cache, das war nur Pentium 4. Der uop-cache in Sandybridge / Ryzen ist das nicht eine trace cache; es folgt nicht springt. Plus, legacy-decode Bandbreite ist erheblich besser als in P4, also uop cache-misses sind keine Katastrophe. Aber ja,O2
könnte besser sein, insgesamt für einige große Programme wenn L1i findet sind ein problem.-O3
macht nicht aktivieren-funroll-loops
; das ist nur für den hot-loops wenn Sie das tun PGO mit-fprofile-generate
/`-fprofile-use
. Auch die GCC-8 und später in der Regel auto-Vektorisieren mit unaligned load/store statt, der vollständig abgerollt Prolog/Epilog um eine Ausrichtungsgrenze. Das war immer schlecht und super-aufgebläht, die Ausgaben die meisten der code-Größe für eine auto-Vektorgrafik-Schleife auf der Start - / Aufräumen, nicht abrollen des tatsächlichen wichtiger Teil bei allen! BTW, klammerten sich-O2
nicht auto-Vektorisieren, und entrollt kleine Schleifen standardmäßig.