Ile jest poziomów optymalizacji GCC ?
Próbowałem gcc -O1, gcc -O2, gcc -O3 i gcc -O4
Jeśli użyję naprawdę dużej liczby, to nie zadziała.
Jednak próbowałem
gcc -O100
i to skompilowane.
Ile jest poziomów optymalizacji?
c
optimization
gcc
compiler-construction
neuromancer
źródło
źródło
man gcc
na Cygwin (12000 nieparzystych wierszy) możesz wyszukać-O
i znaleźć wszystko, co podają poniższe odpowiedzi, a następnie niektóre.3
jest takie samo jak3
(o ile się nieint
przepełnia). Zobacz moją odpowiedź .-fomit-stack-pointer
zmieni wygenerowany kod.Odpowiedzi:
Aby być pedantycznym, istnieje 8 różnych poprawnych opcji -O, które możesz dać gcc, chociaż jest kilka, które oznaczają to samo.
W pierwotnej wersji tej odpowiedzi podano 7 opcji. Od tego czasu GCC dodał,
-Og
aby uzyskać łączną liczbę 8Ze strony podręcznika :
-O
(Tak samo jak-O1
)-O0
(nie optymalizuj, wartość domyślna, jeśli nie określono poziomu optymalizacji)-O1
(optymalizuj minimalnie)-O2
(optymalizuj więcej)-O3
(optymalizuj jeszcze bardziej)-Ofast
(optymalizacja bardzo agresywna do momentu złamania zgodności ze standardami)-Og
(Optymalizuj działanie debugowania. -Og włącza optymalizacje, które nie kolidują z debugowaniem. Powinien to być poziom optymalizacji wybrany dla standardowego cyklu edycja-kompilacja-debugowanie, oferujący rozsądny poziom optymalizacji przy jednoczesnym zachowaniu szybkiej kompilacji i dobrych wrażeń z debugowania. )-Os
(. Optymalizacja dla rozmiaru-Os
włącza wszystkie-O2
optymalizacje, które zazwyczaj nie zwiększają rozmiar kodu wykonuje również dalsze optymalizacje zaprojektowane w celu zmniejszenia rozmiaru kodu..-Os
Wyłącza następujące flagi optymalizacji:-falign-functions -falign-jumps -falign-loops -falign-labels -freorder-blocks -freorder-blocks-and-partition -fprefetch-loop-arrays -ftree-vect-loop-version
)Mogą również istnieć optymalizacje specyficzne dla platformy, jak zauważa @pauldoo, OS X.
-Oz
źródło
-Oz
ustawienie, które jest „optymalizuj pod kątem rozmiaru bardziej agresywnie niż-Os
”: developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/ ...-Og
, czyli wszystkie opcje optymalizacji, które nie kolidują z debugowaniemSpójrzmy prawdzie w interpretacji kodu źródłowego GCC 5.1 , aby zobaczyć, co dzieje się
-O100
, ponieważ nie jest jasne, na stronie man.Wnioskujemy, że:
-O3
doINT_MAX
jest takie samo jak-O3
, ale może się to łatwo zmienić w przyszłości, więc nie polegaj na tym.INT_MAX
.-O-1
Skoncentruj się na podprogramach
Po pierwsze należy pamiętać, że GCC jest tylko front-end dla
cpp
,as
,cc1
,collect2
. Krótko./XXX --help
mówiąc, tylkocollect2
icc1
bierz-O
, więc skupmy się na nich.I:
daje:
więc
-O
został przekazany do obucc1
icollect2
.O in common.opt
common.opt to specyficzny dla GCC format opisu opcji CLI opisany w wewnętrznej dokumentacji i przetłumaczony na C przez opth-gen.awk i optc-gen.awk .
Zawiera następujące interesujące wiersze:
które określają wszystkie
O
opcje. Zwróć uwagę, jak-O<n>
jest w osobnej rodziny z drugiej stronyOs
,Ofast
iOg
.Kiedy budujemy, generuje
options.h
plik, który zawiera:Jako bonus, gdy grepujemy do
\bO\n
środkacommon.opt
, zauważamy linie:co nas uczy, że
--optimize
(podwójny myślnik, ponieważ zaczyna się od myślnika-optimize
w.opt
pliku) jest nieudokumentowanym aliasem,-O
którego można użyć jako--optimize=3
!Gdzie OPT_O jest używany
Teraz grep:
co wskazuje nam na dwa pliki:
Najpierw wytropmy
opts.c
opts.c: default_options_optimization
Wszystkie
opts.c
zwyczaje zdarzyć wewnątrz:default_options_optimization
.Wykonujemy grep backtrack, aby zobaczyć, kto wywołuje tę funkcję i widzimy, że jedyna ścieżka do kodu to:
main.c:main
toplev.c:toplev::main
opts-global.c:decode_opts
opts.c:default_options_optimization
i
main.c
jest punktem wejściacc1
. Dobry!Pierwsza część tej funkcji:
integral_argument
która wywołujeatoi
ciąg odpowiadający do,OPT_O
aby przeanalizować argument wejściowyopts->x_optimize
gdzieopts
jeststruct gcc_opts
.struct gcc_opts
Po grepowaniu na próżno zauważamy, że
struct
jest to również generowane pod adresemoptions.h
:skąd
x_optimize
pochodzi z linii:obecny w
common.opt
i żeoptions.c
:więc domyślamy się, że to właśnie zawiera cały stan globalny konfiguracji i
int x_optimize
jest wartością optymalizacji.255 to wewnętrzne maksimum
in
opts.c:integral_argument
,atoi
jest stosowany do argumentu wejściowego, więcINT_MAX
jest to górna granica. A jeśli umieścisz coś większego, wydaje się, że GCC uruchamia niezdefiniowane zachowanie C. Auć?integral_argument
również cienko zawijaatoi
i odrzuca argument, jeśli którykolwiek znak nie jest cyfrą. Zatem wartości ujemne zawodzą wdzięcznie.Wracając do
opts.c:default_options_optimization
, widzimy wiersz:tak aby poziom optymalizacji został obcięty do
255
. Podczas czytaniaopth-gen.awk
natknąłem się na:i na wygenerowanych
options.h
:co wyjaśnia, dlaczego obcięcie: opcje muszą być również przekazane do
cl_optimization
, który używa a,char
aby zaoszczędzić miejsce. Tak więc 255 jest właściwie wewnętrznym maksimum.opts.c: może_default_options
Wracając do
opts.c:default_options_optimization
, natrafiliśmy na to,maybe_default_options
co brzmi interesująco. Wchodzimy do niego, a potemmaybe_default_option
docieramy do dużego przełącznika:Nie ma
>= 4
kontroli, co oznacza, że3
jest to możliwie największe.Następnie szukamy definicji
OPT_LEVELS_3_PLUS
wcommon-target.h
:Ha! To mocny wskaźnik, że istnieją tylko 3 poziomy.
opts.c: default_options_table
opt_levels
jest tak interesujący, że grepujemyOPT_LEVELS_3_PLUS
i natrafiamy naopts.c:default_options_table
:więc w tym miejscu
-On
jest kodowane mapowanie optymalizacyjne do określonego, o którym mowa w dokumentacji. Miły!Upewnij się, że x_optimize nie ma już zastosowań
Głównym zastosowaniem
x_optimize
było ustawienie innych specyficznych opcji optymalizacji, takich-fdefer_pop
jak udokumentowane na stronie podręcznika. Czy jest ich więcej?My
grep
i znajdujemy kilka innych. Liczba jest niewielka i po ręcznym sprawdzeniu widzimy, że każde użycie powoduje co najwyżej ax_optimize >= 3
, więc nasz wniosek jest ważny.lto-wrapper.c
Teraz przejdźmy do drugiego wystąpienia
OPT_O
, które było wlto-wrapper.c
.LTO oznacza optymalizację czasu łącza, która, jak nazwa sugeruje, będzie potrzebować
-O
opcji i będzie połączona zcollec2
(co jest w zasadzie konsolidatorem).W rzeczywistości pierwsza linijka
lto-wrapper.c
mówi:W tym pliku
OPT_O
wystąpienia wydają się tylko normalizować wartość,O
aby przekazać ją dalej, więc powinno być dobrze.źródło
Siedem różnych poziomów:
-O0
(domyślnie): brak optymalizacji.-O
lub-O1
(to samo): Optymalizuj, ale nie trać zbyt wiele czasu.-O2
: Bardziej agresywna optymalizacja-O3
: Optymalizuj najbardziej agresywnie-Ofast
: Odpowiednik-O3 -ffast-math
.-ffast-math
wyzwala niezgodne ze standardami optymalizacje zmiennoprzecinkowe. Pozwala to kompilatorowi udawać, że liczby zmiennoprzecinkowe są nieskończenie dokładne, a ich algebra jest zgodna ze standardowymi zasadami algebry liczb rzeczywistych. Mówi również kompilatorowi, aby nakazał sprzętowi opróżnienie denormali do zera i traktowanie denormali jako zero, przynajmniej na niektórych procesorach, w tym x86 i x86-64. Denormale wyzwalają powolną ścieżkę na wielu FPU, więc traktowanie ich jako zero (co nie wyzwala wolnej ścieżki) może być dużą wygraną w wydajności.-Os
: Optymalizacja pod kątem rozmiaru kodu. W niektórych przypadkach może to faktycznie zwiększyć szybkość dzięki lepszemu zachowaniu pamięci podręcznej I.-Og
: Optymalizuj, ale nie koliduj z debugowaniem. Umożliwia to niezakłócającą wydajność kompilacji debugowania i ma zastąpić-O0
kompilacje debugowania.Istnieją również inne opcje, które nie są włączane przez żadną z nich i muszą być włączone oddzielnie. Możliwe jest również użycie opcji optymalizacji, ale wyłącz określone flagi włączone przez tę optymalizację.
Więcej informacji można znaleźć na stronie internetowej GCC.
źródło
-O100
kompiluje się?Cztery (0-3): Patrz GCC 4.4.2 instrukcji . Cokolwiek wyższe to tylko -O3, ale w pewnym momencie przekroczysz limit rozmiaru zmiennej.
źródło
atoi
niezdefiniowanym zachowaniu, po którym następuje255
wewnętrzny limit.