Wie viele GCC- Optimierungsstufen gibt es?
Ich habe gcc -O1, gcc -O2, gcc -O3 und gcc -O4 ausprobiert
Wenn ich eine wirklich große Anzahl verwende, funktioniert es nicht.
Ich habe es jedoch versucht
gcc -O100
und es kompiliert.
Wie viele Optimierungsstufen gibt es?
c
optimization
gcc
compiler-construction
Neuromant
quelle
quelle
man gcc
auf Cygwin (12000 ungerade Zeilen) können Sie-O
alles suchen und finden, was die Antworten unten angeben, und noch einige mehr.3
das gleiche wie3
(solange es nichtint
überläuft). Siehe meine Antwort .-fomit-stack-pointer
ändert den generierten Code.Antworten:
Um pedantisch zu sein, gibt es 8 verschiedene gültige -O-Optionen, die Sie gcc geben können, obwohl es einige gibt, die dasselbe bedeuten.
In der Originalversion dieser Antwort wurden 7 Optionen angegeben. GCC hat seitdem hinzugefügt
-Og
, um die Summe auf 8 zu bringenVon der Manpage:
-O
(Gleich wie-O1
)-O0
(Keine Optimierung durchführen, Standardeinstellung, wenn keine Optimierungsstufe angegeben ist)-O1
(minimal optimieren)-O2
(mehr optimieren)-O3
(noch mehr optimieren)-Ofast
(sehr aggressiv optimieren, bis die Standardkonformität verletzt wird)-Og
(Optimieren der Debugging-Erfahrung. -Og ermöglicht Optimierungen, die das Debuggen nicht beeinträchtigen. Dies sollte die Optimierungsstufe der Wahl für den Standard-Zyklus zum Bearbeiten, Kompilieren und Debuggen sein, die ein angemessenes Optimierungsniveau bietet und gleichzeitig eine schnelle Kompilierung und eine gute Debugging-Erfahrung gewährleistet. )-Os
(. Optimize for Größe-Os
ermöglicht es, alle-O2
Optimierungen , die typischerweise keine Codegröße erhöhen Sie führt auch weitere Optimierungen entwickelt , die Codegröße zu reduzieren..-Os
Deaktiviert die folgenden Optimierungen:-falign-functions -falign-jumps -falign-loops -falign-labels -freorder-blocks -freorder-blocks-and-partition -fprefetch-loop-arrays -ftree-vect-loop-version
)Es kann auch plattformspezifische Optimierungen geben, wie OSpa feststellt, hat @pauldoo
-Oz
quelle
-Oz
Einstellung, die "aggressiver für die Größe optimieren als-Os
" ist: developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/…-Og
alle Optimierungsoptionen, die das Debuggen nicht beeinträchtigenLassen Sie uns den Quellcode von GCC 5.1 interpretieren, um zu sehen, was passiert,
-O100
da dies auf der Manpage nicht klar ist.Wir werden daraus schließen, dass:
-O3
,INT_MAX
ist dasselbe wie-O3
, aber das könnte sich in Zukunft leicht ändern. Verlassen Sie sich also nicht darauf.INT_MAX
.-O-1
Konzentrieren Sie sich auf Unterprogramme
Zunächst erinnert , dass GCC ist nur ein Front-End für
cpp
,as
,cc1
,collect2
. Ein kurzer./XXX --help
sagt das nurcollect2
undcc1
nimm-O
, also konzentrieren wir uns auf sie.Und:
gibt:
so
-O
wurde an beidecc1
und weitergeleitetcollect2
.O gemeinsam.opt
common.opt ist ein GCC-spezifisches CLI-Optionsbeschreibungsformat, das in der internen Dokumentation beschrieben und von opth-gen.awk und optc-gen.awk in C übersetzt wird .
Es enthält die folgenden interessanten Zeilen:
die alle
O
Optionen angeben . Beachten Sie, wie-O<n>
in einer von der anderen Familie getrennt istOs
,Ofast
undOg
.Beim Erstellen wird eine
options.h
Datei generiert, die Folgendes enthält:Als Bonus bemerken wir , während wir nach
\bO\n
innen greifencommon.opt
, die Zeilen:Das lehrt uns, dass
--optimize
(doppelter Bindestrich, da er mit einem Bindestrich-optimize
in der.opt
Datei beginnt ) ein undokumentierter Alias ist, für-O
den verwendet werden kann als--optimize=3
!Wo OPT_O verwendet wird
Jetzt grep wir:
was uns auf zwei Dateien verweist:
Lassen Sie uns zuerst aufspüren
opts.c
opts.c: default_options_optimization
Alle
opts.c
Verwendungen erfolgen innerhalb :default_options_optimization
.Wir greifen nach dem Backtrack, um zu sehen, wer diese Funktion aufruft, und wir sehen, dass der einzige Codepfad ist:
main.c:main
toplev.c:toplev::main
opts-global.c:decode_opts
opts.c:default_options_optimization
und
main.c
ist der Einstiegspunkt voncc1
. Gut!Der erste Teil dieser Funktion:
integral_argument
wasatoi
die Zeichenfolge aufruft, dieOPT_O
dem Analysieren des Eingabearguments entsprichtopts->x_optimize
wo aopts
iststruct gcc_opts
.struct gcc_opts
Nachdem wir vergeblich gegriffen haben, stellen wir fest, dass dies
struct
auch generiert wird beioptions.h
:wo
x_optimize
kommt aus den Zeilen:vorhanden in
common.opt
und dassoptions.c
:Wir vermuten also, dass dies den gesamten globalen Konfigurationsstatus und
int x_optimize
den Optimierungswert enthält.255 ist ein internes Maximum
in
opts.c:integral_argument
,atoi
wird auf das Eingabeargument angewendet, ebensoINT_MAX
eine Obergrenze. Und wenn Sie etwas Größeres hinzufügen, scheint es, dass GCC C undefiniertes Verhalten ausführt. Autsch?integral_argument
Außerdem wirdatoi
das Argument dünn umbrochen und zurückgewiesen, wenn ein Zeichen keine Ziffer ist. Negative Werte scheitern also anmutig.Zurück zu sehen
opts.c:default_options_optimization
wir die Linie:so dass die Optimierungsstufe auf abgeschnitten wird
255
. Beim Lesen waropth-gen.awk
ich auf Folgendes gestoßen:und auf dem generierten
options.h
:Das erklärt, warum die Kürzung: Die Optionen müssen auch weitergeleitet werden
cl_optimization
, wodurch einchar
Platz spart. 255 ist also tatsächlich ein internes Maximum.opts.c: vielleicht_default_options
Zurück zu
opts.c:default_options_optimization
, wir stoßen auf das,maybe_default_options
was interessant klingt. Wir betreten es undmaybe_default_option
erreichen dann einen großen Schalter:Es gibt keine
>= 4
Überprüfungen, was darauf hinweist, dass dies3
die größtmögliche ist.Dann suchen wir nach der Definition von
OPT_LEVELS_3_PLUS
incommon-target.h
:Ha! Dies ist ein starker Indikator dafür, dass es nur 3 Ebenen gibt.
opts.c: default_options_table
opt_levels
ist so interessant, dass wir grepOPT_LEVELS_3_PLUS
und stoßen aufopts.c:default_options_table
:Hier wird also
-On
die in den Dokumenten erwähnte Zuordnung zur spezifischen Optimierung codiert. Nett!Stellen Sie sicher, dass x_optimize nicht mehr verwendet wird
Die Hauptverwendung von
x_optimize
bestand darin, andere spezifische Optimierungsoptionen festzulegen, wie sie-fdefer_pop
auf der Manpage dokumentiert sind. Gibt es noch mehrWir
grep
und finden ein paar mehr. Die Anzahl ist gering, und bei manueller Prüfung stellen wir fest, dass jede Verwendung höchstens a bewirktx_optimize >= 3
, so dass unsere Schlussfolgerung gilt.lto-wrapper.c
Jetzt gehen wir zum zweiten Vorkommen von
OPT_O
, das in warlto-wrapper.c
.LTO bedeutet Link Time Optimization, für die, wie der Name schon sagt, eine
-O
Option erforderlich ist und mit der verknüpft wirdcollec2
(was im Grunde genommen ein Linker ist).In der Tat
lto-wrapper.c
sagt die erste Zeile von :In dieser Datei
OPT_O
scheinen die Vorkommen nur den Wert vonO
zu normalisieren , um ihn weiterzuleiten, also sollten wir in Ordnung sein.quelle
Sieben verschiedene Ebenen:
-O0
(Standard): Keine Optimierung.-O
oder-O1
(dasselbe): Optimieren, aber nicht zu viel Zeit verbringen.-O2
: Aggressiver optimieren-O3
: Am aggressivsten optimieren-Ofast
: Entspricht-O3 -ffast-math
.-ffast-math
löst nicht standardkonforme Gleitkommaoptimierungen aus. Auf diese Weise kann der Compiler vorgeben, dass Gleitkommazahlen unendlich genau sind und dass die Algebra auf ihnen den Standardregeln der reellen Zahlenalgebra folgt. Außerdem wird der Compiler angewiesen, die Hardware anzuweisen, Denormals auf Null zu setzen und Denormals zumindest auf einigen Prozessoren, einschließlich x86 und x86-64, als Null zu behandeln. Denormale lösen bei vielen FPUs einen langsamen Pfad aus. Wenn Sie sie daher als Null behandeln (was den langsamen Pfad nicht auslöst), kann dies einen großen Leistungsgewinn bedeuten.-Os
: Für Codegröße optimieren. Dies kann in einigen Fällen die Geschwindigkeit aufgrund eines besseren I-Cache-Verhaltens verbessern.-Og
: Optimieren, aber das Debuggen nicht beeinträchtigen. Dies ermöglicht eine nicht peinliche Leistung für Debug-Builds und soll-O0
Debug-Builds ersetzen .Es gibt auch andere Optionen, die von keiner dieser Optionen aktiviert werden und separat aktiviert werden müssen. Es ist auch möglich, eine Optimierungsoption zu verwenden, jedoch bestimmte durch diese Optimierung aktivierte Flags zu deaktivieren.
Weitere Informationen finden Sie auf der GCC-Website.
quelle
-O100
kompiliert dann?Vier (0-3): Siehe GCC 4.4.2- Handbuch . Alles, was höher ist, ist nur -O3, aber irgendwann wird die variable Größenbeschränkung überschritten.
quelle
atoi
undefiniertes Verhalten zu stützen , gefolgt von einer255
internen Grenze.