Flagi optymalizacyjne
4 08 2008Flagi optymalizacyjne stosowane są, by zoptymalizować kod binarny pod daną architekturę procesora, na którym będzie on używany. Daje to, powiedzmy, kilkuprocentowy zysk w szybkości działania. Kreując paczkę, zawsze ustawiam je w odpowiednim miejscu. W końcu nie pozwolimy, żeby procesor niepotrzebnie się grzał ani nie będziemy się zniżać do poziomu na Slacky, gdzie w większości przypadków nie obchodzi ich to, czy podanie przez nich flag jest skuteczne.
Flagi najczęściej zapisywane są w pliku Makefile lub w innym pliku nagłówkowym systemu budującego, który jest później include’owany. Koniec końców przekazywane są one do kompilatora w postaci parametru poprzez użycie zmiennej. Dzisiaj chcę podać przykłady ustawiania flag, z jakimi napotkałem się w mojej karierze. Lecim na Szczecin.
Żeby sprawdzić, czy kod kompiluje się rzeczywiście z podanymi flagami, najprościej jest użyć ps:
ps x | grep <twoja architektura (część flagi)>
Jeśli ukaże nam się linijka z procesem kompilatora, a po nim nasze flagi, to działa. Jak nie, to trzeba się jeszcze trochę pomęczyć.
Teraz przejdę do przykładów. Nie będę używał konkretnych flag, lecz zmiennej z naszego SlackBuilda. $SLKCFLAGS to nasze flagi (przykładowo “-O2 -march=i686 -mcpu=i686″).
configure
Banał. Nawet w –help jest jakiś opis.
CFLAGS="$SLKCFLAGS" CXXFLAGS="$SLKCFLAGS" ./configure
Zwykłe zmienne środowiskowe.
CMake
Poprzez parametr.
cmake -DCMAKE_C_FLAGS:PATH="$SLKCFLAGS" -DCMAKE_CXX_FLAGS:PATH="$SLKCFLAGS"
Bootstrap
Zupełnie jak w przypadku configure.
CFLAGS="$SLKCFLAGS" CXXFLAGS="$SLKCFLAGS" ./bootstrap
QMake
Tutaj sprawa ma się często różnie, bo zależy to od twórcy pakietu, jak postanowi użyć QMake. Najczęściej poprzez zmienną podaną przez argument.
make qmake_all QMAKE="/usr/lib/qt-4*/bin/qmake QMAKE_CFLAGS="$SLKCFLAGS" QMAKE_CXXFLAGS="$SLKCFLAGS""
Tutaj byłem zmuszony do przyklejenia flag razem ze ścieżką do qmake.
qmake QMAKE_CFLAGS_RELEASE="$SLKCFLAGS" QMAKE_CXXFLAGS_RELEASE="$SLKCFLAGS"
make CFLAGS="$SLKCFLAGS" CXXFLAGS="$SLKCFLAGS"
Gdy make uruchamia qmake, można i tak.
SCons
Czasami najzwyklej.
CFLAGS="$SLKCFLAGS" CXXFLAGS="$SLKCFLAGS" ./scons
…ale może się zdarzyć, że twórcy są mądrzejsi od nas i sami chcą dobrać flagi, a my dajemy im tylko architekturę.
scons DIST_TARGET="$ARCH"
BJam
Wyjątkowo nieprzyjazny dla użytkownika, a nawet dla dewelopera, system. W dokumentacji nic nie znalazłem, więc pozostało mi tylko:
sed -i "s@flags gcc.compile OPTIONS <optimization>speed : -O3 ;@flags gcc.compile OPTIONS <optimization>speed : $SLKCFLAGS ;@" tools/build/v2/tools/gcc.jam
Make
Gdy w systemie jest samo Makefile bez wcześniej generujących go skryptów, pozostaje nam podać flagi w postaci zmiennej, z tym że za każdym uruchomieniem, a nie tylko raz, ponieważ one nie są nigdzie zapisywane.
make CFLAGS="$SLKCFLAGS" CXXFLAGS="$SLKCFLAGS"
make GCCFLAG="$SLKCFLAGS"
Shit
Nie, nie istnieje system budujący o nazwie Shit. Chodzi o najzwyklejsze w świecie nieprzystosowane do użycia flag systemy, wykluczając te, w których dokumentacji zostało powiedziane, jak podać flagi (ale że są niepopularne, to ich nie opisałem). W takim przypadku nie zadziałają podane wcześniej sposoby. Natrafiałem np. na niedziałające w tym względzie configure… Wtedy musimy przyznać, że deweloper się nie popisał, więc nie pozostaje nam nic, jak popisać się samemu. Najczęściej wypada użyć sed, czy samodzielnie zmodyfikować plik (niedopuszczalne, gdy piszemy SB).
sed -i "s@-O2@$SLKCFLAGS@" `find . -name flags.make`
sed -i "s@CXXFLAGS.*=@CXXFLAGS=$SLKCFLAGS @" `find . -name Makefile`
Każemy sed-owi zamienić charakterystyczne elementy jak “-O2″ (też flaga, ale my chcemy bardziej sprecyzowanych) na nasze flagi. Jeżeli w Makefile nie ma kompletnie zmiennej służącej do przechowywania ich, posługujemy się inną powszechną zmienną (dopisujemy do niej) występującą przy kompilacji bądź wykazujemy się jeszcze większym sprytem.
Przede wszystkim należy pamiętać, że każdy przypadek jest indywidualny. Sami musimy przejrzeć skrypty budujące bądź dokumentację. Proszę się też nie wygłupiać, starając się wcisnąć flagi do procesu instalacji skryptów Pythona czy innych. Flagi optymalizacyjne dotyczą tylko kompilacji, a skryptów się nie kompiluje.



Błąd, ze nie użyłeś prawdziwych flag dla jakiegoś procesora. Niestety miedzy luźnymi opisami a prawdziwymi przykładami jest morze nieudanych testów.
Z całego wpisu również nie dowiedziałem się co konkretnie mam zrobić. Takie teoretyczne dywagacje, nic praktycznego w użyciu.
Co rozumiesz przez “prawdziwe” flagi? Zresztą projekty takie jak SCXD nie mogą oferować paczek optymalizowanych dla konkretnych procesorów. Tu i tak istnieje odstępstwo od slackware’owej normy i paczki są robione na i686 a nie jak w przypadku Slacka i486 z optymalizacją na i686.
[...] trudno z jego pomocą obsługiwać projekt bazujący przykładowo na popularnym Qt, powstały nowe narzędzia budujące. Jednym z nich jest postępowy [...]
[...] trudno z jego pomocą obsługiwać projekt bazujący przykładowo na popularnym Qt, powstały nowe narzędzia budujące. Jednym z nich jest postępowy [...]