kompilacja programów
Flagi sterujące
optymalizacją w GCC
Grzegorz Niewęgłowski
okół kompilatora GCC Flaga -march powoduje wykorzystanie
i jego możliwości opty- wszystkich cech specyficznych danego
malizacji kodu, jak rów- modelu procesora, nawet jeśli zrywa to
Wnież samej kompilacji, kompatybilność ze starszymi modelami,
krąży w środowisku linuksowym wiele np. zezwala na tworzenie kodu używa-
informacji, często sprzecznych. W poniż- jącego dodatkowych rejestrów procesora
szym artykule przedstawię podstawowe czy rozszerzonych zestawów instrukcji,
fakty dotyczące optymalizacji GCC. np. MMX. Użycie flagi -march powoduje
Opcje sterujące optymalizacją od razu ciche włączenie blizniaczej flagi
w GCC można z grubsza podzielić na -mtune. Ramka Wybór architektury proce-
dwie grupy: optymalizację pod konkret- sora w GCC (3.4.0) pokazuje zależność
ną architekturę oraz optymalizację szcze-
gółową, przy której decyduje się o takich
Wybór architektury
niuansach, jak redukowanie zbędnych
pętli w kodzie, usuwanie niewykorzy- procesora w GCC (3.4.0)
Procesor 386: -march=i386
stanych zmiennych, sterowanie użyciem
Procesor 486: -march=i486
rejestrów procesora itp. Takie opcje GCC
Procesor 586 (Pentium): -march=i586
nazywa się zwykle flagami. Używanie
lub -march=pentium
flag może mieć wpływ na stabilność
(te dwie opcje są równoznaczne)
i poprawność działania programów ze
WinChip: -march=winchip-c6,
względu na błędy w programach lub
-march=winchip2
samym kompilatorze. Z tego powodu,
Via C3: -march=c3, -march=c3-2
jeśli zauważysz jakieś błędne zachowa-
nia, spróbuj skompilować kod jeszcze raz, Procesory Intel:
Pentium MMX: -march=pentium-mmx
bez własnych optymalizacji, a następnie
Pentium Pro (pierwsze i686):
stopniowo dodawać poszczególne flagi,
-march=i686 lub -march=pentium-
aż znajdziesz winowajcę.
pro (te dwie opcje są równoznaczne)
Procesor Pentium2: -march=pentium2
Wybór typu procesora
Na płycie CD/DVD
Procesor Pentium3: -march=pentium3
Typ procesora wybiera się za pomocą
Na płycie CD/DVD znajdują się
Procesor Pentium4: -march=pentium4
dwóch flag: -mtune= oraz -march=.
pakiety zródłowe nowego GCC.
Flaga -mtune (znana również jako
Procesory AMD:
O autorze
-mcpu) wybiera schemat kolejkowania
Procesor K6: -march=k6
Autor od kilku lat używa Linuksa
instrukcji procesora. Odpowiednio ukła- Procesor K6-2: -march=k6-2
jako jedynego systemu opera-
Procesor K6-3: -march=k6-3
dając kolejność napływania rozkazów do
cyjnego. Aktywnie uczestniczy
Zwykły Athlon: -march=athlon
procesora, można czasem przyspieszyć
w polskich grupach dyskusyj-
Athlon Thunderbird: -march=athlon-
ich realizację. Już procesory Pentium
nych poświęconych Linuksowi,
tbird
potrafiły w pewnych sytuacjach wykony-
jak również prowadzi nieduży
Athlon4: -march=athlon-4
wać dwa rozkazy równolegle. Takie zmie-
internetowy kącik dotyczący
AthlonXP: -march=athlon-xp
nianie kolejności rozkazów nie zrywa
zagadnień związanych z tym
AthlonMP: -march=athlon-mp
kompatybilności z innymi modelami
systemem. Kontakt z autorem:
Rodzina AMD64 - do wyboru: k8,
autorzy@linux.com.pl procesorów one po prostu nie odniosą
opteron, athlon64, athlon-fx
z tego powodu żadnych korzyści.
50
sierpień 2004
gcc kompilacja programów
Nie ma sensu używanie -O3 przy kompi-
lacji całego systemu. Pamiętajmy też, że
-O3 powoduje przyrost objętości kodu,
co może być fatalne dla procesorów
z niewielką pamięcią podręczną (cache),
takich jak Celerony czy Durony.
Czasem widuje się flagi typu -O6 lub
nawet -O99. Nie są to żadne dodatkowe
tajne optymalizacje, bo aktualne GCC
nie obsługują niczego mocniejszego niż
-O3. Podając wyższe wartości, GCC i tak
użyje -O3.
Jeśli w wywołaniu GCC podamy
kilka wartości -Ox, to GCC użyje tej
podanej najpózniej.
Inne popularne flagi
GCC pozwala na drobiazgowe sterowanie
optymalizacją przy użyciu kilkudziesięciu
flag, z których jedynie kilka jest wartych
uwagi.
Rysunek 1. Przykładowe zależności między optymalizacją a wielkością kompilatu
-ffast-math
i wydajnością
Ta flaga może spowodować (niezbyt
pomiędzy modelem procesora a warto- Najczęściej używa się flagi -O2, włącza- duże) przyspieszenie wykonywania nie-
ścią -march. jącej najpopularniejszy zestaw optyma- których obliczeń matematycznych (np.
Jeśli nie widzisz na liście swojego lizacji. Opcja -O3 jest specjalna po jej funkcji trygonometrycznych), ale dzieje
procesora, to wybierz ten, który jest mu włączeniu GCC używa prawie wszystkich się to poprzez naginanie standardów
technologicznie najbliższy, np. dla pierw- dostępnych trików, aby uzyskać szybszy IEEE/ISO, dotyczących takich obliczeń.
szych Celeronów będzie to pentium2, kod binarny, ale natura optymalizacji Jeśli autor kodu zakładał pełną zgod-
a dla AMD K5 będzie to i586. Proceso- wywoływanych przez -O3 jest trudna do ność funkcji matematycznych z wyżej
ry AMD Duron to w zasadzie zwykłe przewidzenia i zmienia się w zależności wymienionymi standardami, to kod
Athlony, tyle że z okrojoną pamięcią od konkretnego kompilowanego kodu. może zacząć produkować błędne wyniki.
podręczną procesora (relacja między Zwykle -O3 spowoduje rozrośnięcie się Gdy to sam autor kodu zaleca używanie
Duronem a Athlonem jest podobna do tej wynikowego kompilatu (skompilowany tej flagi (np. umieszczając ją w pliku
między Celeronem a Pentium), co znaczy, program będzie zużywał więcej pamięci Makefile), to znaczy że zapewne można
że obowiązuje je zwykle -march=athlon. operacyjnej), tylko czasem daje zauwa- z niej bezpiecznie korzystać, gdyż kod
Szczegółowe informacje o procesorze żalne przyspieszenie, a czasem może był pisany tak, aby -ffast-math mu nie
zainstalowanym w danej maszynie znaj- nawet doprowadzić do spowolnienia zaszkodziło.
dują się w pliku /proc/cpuinfo. kodu. Z tego powodu to słabsze -O2 jest Włączanie jej globalnie dla wszyst-
najpopularniejszą flagą, bo, w przeci- kich budowanych pakietów to wielki
Wybór siły optymalizacji wieństwie do -O3, oferuje rozsądny (oraz błąd, np. Perl, którego kiedyś skompilo-
GCC oferuje przytłaczająco wielką paletę przewidywalny) kompromis pomiędzy wałem z -ffast-math, nie umiał przejść
flag, z których możesz skorzystać. Aby wydajnością a rozmiarem kodu. przez zestaw testowy weryfikujący
ułatwić ich stosowanie, powstały specjal- Bardzo interesująca jest opcja -Os. poprawność kompilacji. Błędnie wyko-
ne zbiorcze opcje -Ox. Do wyboru mamy Jest to specjalny wariant flagi -O2, zorien- nywał niektóre operacje arytmetyczne.
-O0, -O1, -O2, -O3 i -Os. Użycie którejś towany na generowanie mniejszego kodu Tą flagą łatwo jest wywołać błędy trudne
z flag -O powoduje włączenie określone- wykonywalnego. Włącza on prawie do wykrycia.
go zestawu innych flag. Jak widać, flagi wszystkie optymalizacje -O2 i dodatkowo
-O są numerowane od 0 do 3 (pomijając używa kilku technik, aby zmniejszyć -mfpmath=sse
-Os) i te cyfry generalnie odpowiadają wynikowy kompilat. Flaga -Os pozwala To flaga przeznaczona dla procesorów
sile optymalizacji. Im wyższa liczba, tym zmniejszyć zapotrzebowanie na pamięć z zestawem instrukcji SSE (przede
mocniej GCC stara się zoptymalizować operacyjną przy zachowaniu wydajności wszystkim Pentium3, AMD Athlon lub
kod (optymalizacje powodują też wydłu- bardzo zbliżonej do -O2. nowsze w razie wątpliwości zajrzyj do
żenie procesu kompilacji). Opcja -O0 Najrozsądniejszą opcją uniwersalną /proc/cpuinfo i sprawdz, czy sse figuruje
wyłącza wszelką optymalizację i raczej jest -Os lub -O2. Z -O3 korzystajmy tylko, w linii flags:). Dzięki tej fladze kod
się jej nie używa. Opcja -O1 włącza pod- gdy mamy absolutną pewność, że da będzie używał nowocześniejszych
stawowe procedury przyspieszania kodu, to wymierny zysk (np. autor kodu tak i szybszych instrukcji SSE, zamiast
ale również rzadko widuje się ją w akcji. twierdzi albo samemu to sprawdziliśmy). odwoływania się do antycznego już
51
www.lpmagazine.org
kompilacja programów
S
zmiennoprzecinkowego koprocesora -s CFLAGS="-march=athlon-xp
matematycznego i387 (wbudowanego GCC, podczas normalnej kompilacji, -O2 -fomit-frame-pointer -s -pipe"
S
w każdy współczesny procesor x86). umieszcza w binarnych plikach wyni- CXXFLAGS="-march=athlon-xp
Flaga ta może dać naprawdę solidny kowych dużo informacji dotyczących -O2 -fno-rtti -fno-exceptions -s -pipe"
przyrost wydajności w aplikacjach nazw funkcji i zmiennych użytych
zajmujących się obliczeniami matema- w kodzie zródłowym. Informacje te nie Istnieje jeszcze zmienna CPPFLAGS. Nie-
tycznymi (np. programach do rende- są wykorzystywane przy normalnym którzy omyłkowo biorą ją za optymalizację
rowania grafiki 3D), więc jeśli masz uruchamianiu binarki, ale pozwalają C++, ale to nieprawda. Owo CPP oznacza
procesor obsługujący SSE, to nie zapom- użyć tzw. debuggera, czyli programu bowiem C PreProcessor i nie ma nic wspól-
nij o niej. do śledzenia wykonywania się kodu. nego z optymalizacjami. Flagi dla C++ usta-
Istnieje jeszcze specjalna wariacja tej Pozwala to programistom wychwy- wia się poprzez zmienną CXXFLAGS.
flagi: -mfpmath=sse,387. Sprawia ona, że tywać błędy w kodzie zródłowym
GCC generuje kod używający równocze- poprzez obserwowanie zawartości Instrukcje MMX, SSE itp.
śnie klasycznego koprocesora 387, jak zmiennych w trakcie wykonywania Czasem spotyka się zestawy flag typu
również nowej jednostki SSE. Teoretycz- się programu. Zwykły użytkownik, jak -march=athlon-xp -msse -mmmx -m3dnow.
nie powoduje to dalsze przyspieszenie, łatwo się domyślić, nie analizuje kodu Zwykle jest to zbędne dublowanie flag,
ale może zakłócić stabilność. w debuggerach. Dlatego istnieje flaga bo odpowiednie dobranie wartości dla
Posiadacze pierwszych Athlonów -s, która wyłącza wsparcie dla debug- -march powinno automatycznie włączyć
(używających -march=athlon lub -mar- gera. Nie przyspieszy to działania wszystkie dodatkowe zestawy instrukcji.
ch=athlon-tbird) będą zapewne musieli kompilatu, ale skróci czas potrzebny na Przykładowo, włączanie każdego pro-
dodać jeszcze flagę -msse, gdyż dla tych kompilacjęi znacząco zmniejszy wielkość cesora od Pentium2 w górę, włącza też
procesorów GCC nie włącza domyślnie plików produkowanych przez kompi- zestaw instrukcji MMX. Można się o tym
obsługi SSE (nie posiadały one jeszcze lator. przekonać używając takich poleceń:
pełnego zestawu instrukcji SSE).
Przekazywanie flag do GCC touch pusty.c
-fomit-frame-pointer Do przekazywania flag kompilatorowi gcc -S -v -Q pusty.c
Ta flaga optymalizuje niektóre funkcje zwykło używać się zmiennych środo-
w kodzie zródłowym sprawiając, że wiskowych. Najważniejsze z nich to GCC wyświetli m.in. fragment options
ich wywoływanie odbywa się szybciej. CFLAGS i CXXFLAGS. Zmienna CFLAGS enabled: zawierający flagi, których kom-
Można spodziewać się po jej użyciu odpowiada za flagi używane przy kom- pilator ma zamiar użyć. Jeśli teraz spróbu-
przyrostu prędkości wykonywania kodu, pilacji programów napisanych w C, jesz wykonać:
spadku jego wielkości oraz mniejsze- a CXXFLAGS steruje optymalizacją pro-
go zużycia pamięci. Współpracuje ona gramów C++. Zmienne te są odczytywa- gcc -S -v -Q pusty.c -march=athlon-xp
jednak tylko z kodem C, a jej użycie dla ne przez większość skryptów ./configure,
kodu C++ ma prawie zawsze opłakane więc po zdefiniowaniu globalnej zmien- zobaczysz, że GCC po włączeniu -march
skutki (większy niż normalnie, błędnie nej CFLAGS, kompilowane aplikacje =athlon-xp automatycznie włączy -mmmx
działający kod). powinny zacząć używać podanych tam -m3dnow -msse. Oczywiście, podawanie
optymalizacji. tych opcji na siłę niczego nie popsuje, ale
-fno-exceptions -fno-rtti Przykładowo, aby zdefiniować roz- warto pamiętać, że przy dobrze ustawio-
Te dwie flagi odnoszą się tylko do kodu sądne flagi dla Athlona XP, można do nym -march dodatki typu -m3dnow rzadko
C++. Powodują wyłączenie pewnych swojego ~/.bashrc dodać następujące kiedy są potrzebne.
mechanizmów kompilatora, sprawiając, wiersze: Optymalizacje kompilatora są tematem
że wynikowy kod binarny jest mniejszy bardzo złożonym. Jak pokazuje ten arty-
S
i szybszy. Niektóre programy C++ nie export CFLAGS="-march=athlon-xp -O2 kuł, można szybko stworzyć sobie całkiem
dadzą się jednak z nią skompilować. -fomit-frame-pointer -s -pipe" dobry i wydajny zestaw flag, jeśli zwróci
S
Najlepiej jest spróbować użyć tych flag export CXXFLAGS="-march=athlon-xp się uwagę na kluczowe elementy.
i ewentualnie wyłączyć je, jeśli kompila- -O2 -fno-rtti -fno-exceptions -s -pipe"
cja się nie powiedzie.
W Internecie:
Już w tym przykładzie widać, dlaczego
-pipe istnieją dwie osobne zmienne dla opty- " Skrypt samodzielnie generujący
zestaw flag na podstawie /proc/
GCC, kompilując jakiś plik, zapisuje malizacji C/C++. C++ nie powinno nigdy
cpuinfo:
sobie pewne dane w plikach tymczaso- otrzymywać flagi -fomit-frame-pointer,
http://www.iol.ie/~padraiga/scripts/
wych. Po użyciu -pipe przestanie używać a kod C zignorowałby flagi -fno-rtti
gcccpuopt
plików tymczasowych, a zamiast nich -fno-exceptions. Z tego powodu zwykle
" Dokładna lista numerów Family/
posłuży się rurkami (potokami). Nie ma flagi dla C nie są identyczne z tymi dla
Model/Stepping dla różnych proceso-
to wpływu na wynikowy kod, więc nie C++. W dystrybucji Gentoo flagi należy
rów:
jest to tak naprawdę flaga sterująca opty- zdefiniować w pliku /etc/make.conf,
http://www.paradicesoftware.com/
malizacją, ale może nieco przyspieszyć w prawie identycznej postaci (pomijając
specs/cpuid/index.htm
samą kompilację. jedynie słowo export):
52
sierpień 2004
Wyszukiwarka
Podobne podstrony:
2004 08 Katalog filmów [Programowanie]2004 09 Rozszerzanie możliwości przeglądarek WWW [Programowanie]2004 07 Konsolowa przeglądarka plików graficznych [Programowanie]08 Integracja Javy z innymi językami, programowanie sieciowe2004 03 CVS – system zarządzania wersjami [Programowanie]2004 08 Tuning KDE i GNOME [Poczatkujacy]Dz U 2004 198 2042 zmiana z dnia 2004 08 272004 12 Piszemy grę w stylu Quake a [Programowanie]2002 08 Programowana tablica świetlnaMS Program Laboratorium 082004 10 14 Optymalizacja wykladyprogram cwiczenia 08 2009 lekarski[1]Ogranicz 2004 07 08Instrukcje sterujące przebiegiem programu2004 10?lipse i Java–program do obliczania sum kontrolnych [Programowanie]więcej podobnych podstron