Podstawy optymalizacji kodu ródłowego
literatura podstawowa [Aho2002] Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman, Kompilatory. Reguły, metody i narzdzia, WNT 2002 (tłum. pierwszego wydania amerykaskiego, 1986). [Aho2001] A.V. Aho, R. Sethi, J.D. Ullman, Compilers: Principles, Techniques, and Tools, Pearson Education 2001. 2
literatura uzupełniajca [Bentley2000] Jon Bentley, Perełki oprogramowania, wyd. trzecie, WNT, 2008 (tłum. drugiego wydania amerykaskiego, Pearson Education 2000). [Bentley2007] Jon Bentley, Wicej perełek oprogramowania. Wyznania programisty, WNT 2007 (tłum. pierwszego wydania amerykaskiego, Pearson Education 1988) 3
literatura uzupełniajca [Kernigham1999] Brian W. Kernigham, Rob Pike, Lekcja programowania, WNT 2002, (tłum. pierwszego wydania amerykaskiego, Pearson Education 1999). [Oram2008] Andy Oram, Greg Wilson (red.), Pikny kod. Tajemnice mistrzów programowania, Helion 2008, (tłum. wydania amerykaskiego, O Reilly Media Inc. 2007). 4
literatura uzupełniajca [Barr2005] Adam Barr, Znajd błd. Sztuka analizowania kodu, Helion 2005 (tłum. wydania amerykaskiego, Pearson Education 2005). 5
Plan wprowadzenie (typowa kompilacja) podstawowe ródła optymalizacji optymalizacja bloków bazowych ptle w grafach przepływu globalna analiza przepływu danych iteracyjne rozwizywanie równa przepływu danych 6
Plan przekształcenia poprawiajce kod obsługa synonimów analiza przepływu danych w strukturalnych grafach przepływu efektywne algorytmy przepływu danych narzdzia do analizy przepływu danych wykrywanie typów 7
Plan symboliczny program uruchomieniowy dla zoptymalizowanego kodu uwagi bibliograficzne 8
kompilator czyta kod w jzyku ródłowym i tłumaczy na kod w jzyku wynikowym [Aho2002] 9
typowa kompilacja [Aho2002] 10
typowa kompilacja program ródłowy w oddzielnych plikach jest składany w cało przez preprocesor, kompilator tworzy kod wynikowy w j. asemblera, tłumaczony nastpnie przez asembler na kod maszynowy i łczony z funkcjami bibliotecznymi 11
typowa kompilacja [Aho2002] 12
fazy kompilatora [Aho2002] 13
fazy kompilatora analiza programu ródłowego generacja kodu poredniego optymalizacja kodu generacja kodu 14
analiza programu ródłowego obejmuje trzy fazy: analiz leksykaln (liniow, skanowanie): strumie znaków grupowany w symbole leksykalne (cigi znaków majce znaczenie) analiz składniow (hierarchiczna, syntaktyczna): symbole leksykalne grupowane w wyraenia gramatyczne (drzewa wyprowadzenia) analiz semantyczn: testy dopasowania składników programu co do znaczenia 15
analiza programu ródłowego analiza programu ródłowego ma na celu wykrycie błdów w programie ródłowym słu do tego pierwsze trzy fazy kompilatora, wymienione przed chwil po analizie programu ródłowego, nastpuje zazwyczaj faza generacji kodu poredniego 16
translacja instrukcji (1) [Aho2002] 17
generacja kodu poredniego kod poredni jest to reprezentacja porednia kodu ródłowego, widziana jako program dla pewnej maszyny abstrakcyjnej reprezentacj t daje si łatwo utworzy i przetłumaczy na program wynikowy 18
generacja kodu poredniego najprostszy algorytm generuje kod poredni, stosujc jeden rozkaz na kady operator w drzewie składniowym [Aho2002] 19
generacja kodu poredniego kod poredni moe mie posta kodu trójadresowego kod trójadresowy to sekwencja rozkazów, z których kady ma co najwyej trzy argumenty 20
generacja kodu poredniego własnoci kodu trójadresowego: kady rozkaz oprócz przypisania moe mie co najwyej jeden operator, dlatego kompilator musi ustali kolejno operacji kompilator musi wygenerowa tymczasowe identyfikatory do zapisu wartoci porednich rozkaz moe mie mniej ni trzy argumenty 21
generacja kodu poredniego przykład kodu trójadresowego [Aho2002]: 22
optymalizacja kodu w fazie tej poprawiamy kod poredni aby stworzy działajcy szybciej kod maszynowy stosuje si tu dwie zasady: konwersja z wartoci całkowitej liczby (np. 60) do rzeczywistej jest wykonana jednorazowo w czasie kompilacji zmienna uywana jednokrotnie w przypisaniu (np. temp3) moe by usunita 23
optymalizacja kodu [Aho2002] z postaci: na posta: 24
optymalizacja kodu w metodach optymalizacji kodu s due rónice w kompilatorach optymalizujcych, znaczna cz czasu kompilacji powicona jest optymalizacji kodu istniej jednak proste metody optymalizacji, niewiele wydłuajce czas optymalizacji 25
generacja kodu ostatni faz kompilacji jest generacja kodu jest to przemieszczalny kod maszynowy albo kod asemblera 26
generacja kodu [Aho2002] z postaci: na posta: 27
generacja kodu w rozkazach tych wystpuj dwa rejestry R1 i R2 pierwszy argument tych rozkazów to ródło, a drugi to przeznaczenie F w nazwie rozkazu oznacza operacje na wartociach zmiennopozycyjnych znak # oznacza, e 60.0 to stała 28
translacja instrukcji (2) [Aho2002] 29
optymalizacja kodu byłoby idealnie, gdyby kompilator wytwarzał kod wynikowy tak dobry, jakby był pisany rcznie ale tak nie jest, kompilator moe jedynie optymalizowa kod w trzech kierunkach: aby działał on szybciej, albo aby zajmował mniej miejsca, albo jedno i drugie 30
optymalizacja kodu kompilatory optymalizujce = poprawiajce kod optymalizacje niezalene od maszyny (nie uwzgldniajce właciwoci maszyny docelowej), na tym si koncentrujemy 31
optymalizacja kodu optymalizacje zalene od maszyny (uwzgldniajce właciwoci maszyny docelowej), to np. alokacja rejestrów i stosowanie specjalnych sekwencji instrukcji maszyny tym zajmiemy si póniej 32
optymalizacja kodu maksymalny efekt uzyskuje si, gdy poprawia si efektywno czsto wykonywanych fragmentów programu czsto zachodzi sytuacja, e mały fragment programu jest odpowiedzialny za istotn cz czasu wykonania programu takie fragmenty naley zidentyfikowa 33
optymalizacja kodu nie jest to trywialne zadanie, kompilator musi to odgadn (nie majc dostpu do przykładowych danych i programu profilujcego) dobrym fragmentem do poprawienia jest wewntrzna ptla w programie, mona j rozpozna po składni programu albo w wyniku analizy przepływu sterowania 34
optymalizacja kodu aby stworzy wydajny program wynikowy, musi istnie współpraca programisty i autora kompilatora opiszemy teraz przekształcenia kodu, poprawiajce wydajno programu obowizuje zasada: najwiksze zyski najmniejszym kosztem 35
kryteria stosowania przekształce poprawiajcych kod cechy przekształce obsługiwanych przez kompilator optymalizujcy: przekształcenie powinno zachowa znaczenie programu przekształcenie powinno przyspiesza program przekształcenie musi si opłaca 36
zachowanie znaczenia programu przekształcenie nie moe zmienia wyjcia programu dla danego wejcia przekształcenie nie moe wprowadza błdu, tam gdzie go nie było - np. dzielenia przez zero zawsze preferowany jest wybór bezpiecznego podejcia 37
przyspieszenie programu dla redniego przypadku nastpuje wymierne przyspieszenie zmniejszenie objtoci generowanego kodu nie dla kadych danych jest przyspieszenie, moe te wystpi spowolnienie 38
opłacalno nie ma sensu poprawianie kodu, jeeli wysiłek ten nie jest doceniony podczas wykonywania programu wynikowego nie ma sensu poprawianie kodu, jeeli dany program zostanie uruchomiony jedynie kilka razy 39
uzyskiwanie lepszej wydajnoci zmniejszenie czasu wykonania programu z godzin do sekund uzyskuje si poprawiajc program na wszystkich poziomach, od programu ródłowego do kodu wynikowego zmiana algorytmu moe przyspieszy czas wykonania programu wielokrotnie, i to w zalenoci od wielkoci danych (przejcie z programu insertion sort na quicksort) 40
uzyskiwanie lepszej wydajnoci kompilator moe zastpi sekwencj operacji inn sekwencj algebraicznie równowan, zmniejszajc czas wykonania programu, szczególnie w programach w jzykach wysokiego poziomu 41
uzyskiwanie lepszej wydajnoci [Aho2002] 42
kod do dowiadczequicksort [Sedgewick1978], [Aho2002] 43
uzyskiwanie lepszej wydajnoci pewnych przekształce poprawiajcych kod nie da si zastosowa na poziomie programu ródłowego mona je jednak wykona na poziomie kodu poredniego programista nie powinien zastpowa kompilatora we wprowadzaniu poprawek do kodu wynikowego 44
struktura kompilatora optymalizujcego 45
struktura kompilatora optymalizujcego pokaemy przekształcenie kodu poredniego faza poprawiania tego kodu obejmuje: analiz przepływu sterowania, analiz przepływu danych, przekształcenia zakładamy, e kod poredni składa si z instrukcji trójadresowych 46
zalety struktury kompilatora optymalizujcego operacje do implementacji konstrukcji wysokiego poziomu s jawne, mona je wic optymalizowa kod poredni jest wzgldnie niezaleny od maszyny docelowej, std niewiele si zmienia, gdy generator kodu dotyczy ju innej maszyny 47
kod trójadresowy dla programu quicksort [Aho2002] 48
graf przepływu dla programu quicksort [Aho2002] 49
graf przepływu dla programu quicksort wszystkie skoki do instrukcji w kodzie trójadresowym zastpiono skokami do bloków, zaczynajcych si od tych instrukcji graf zawiera trzy ptle: B2, B3 oraz B2,B3,B4, B5 50
podstawowe ródła optymalizacji przekształcenia poprawiajce kod: przekształcenie lokalne to takie, które wykonuje si rozpatrujc jedynie instrukcje z jednego bloku bazowego przekształcenie globalne to takie, które wykonuje si rozpatrujc instrukcje z wielu bloków bazowych przekształcenia lokalne wykonuje si jako pierwsze 51
przekształcenia zachowujce funkcj kompilator zmienia program, nie zmieniajc jego funkcji: usuwanie podwyrae wspólnych propagacja kopii usuwanie kodu martwego zwijanie stałych 52
usuwanie podwyrae wspólnych wystpienie wyraenia E jest nazywane podwyraeniem wspólnym, jeeli E było wczeniej obliczone i wartoci zmiennych z E nie zmieniły si po poprzednim obliczeniu unikamy ponownego wyliczenia, mogc uy obliczonej ju wartoci 53
lokalne usuwanie podwyrae wspólnych [Aho2002] t6 zamiast t7, t8 zamiast t10 54
globalne usuwanie podwyrae wspólnych lokalna i globalna eliminacja podwyrae wspólnych bloków B5 i B6 w grafie przepływu dla programu quicksort obliczenie t4 := 4*tj z bloku B3 mona wykorzysta w bloku B5 podstawiajc: t9 := a[t4]; oraz a[t4] := x, zamiast t8 := 4*tj; t9 := a[t8]; a[t8] := x 55
globalne usuwanie podwyrae wspólnych [Aho2002] 56
propagacja kopii blok B5 z ostatniego grafu mona poprawi, usuwajc x przy pomocy przekształcenia nazywanego propagacj kopii dotyczy ono przypisaf : = g, zwanych instrukcjami kopiowania lub kopiami kopie te wprowadza przekształcenie usuwania podwyrae wspólnych 57
propagacja kopii [Aho2002] gdy podwyraenie wspólne w c:= d + e jest usuwane, algorytm uywa zmiennej t do przechowania wartoci d + e nie moemy jednak zastpic := d + e ani przez c := a, ani przez c := b 58
propagacja kopii [Aho2002] propagacja kopii polega na uywaniu g zamiast f po instrukcji f := g na przykład, przypisanie x := t3 w bloku B5 jest kopi dokonujc propagacji kopii otrzymujemy: 59
usuwanie kodu martwego zmienna, której warto nie moe by uyta w danym punkcie programu jest martwa analogicznie rozumiemy kod martwy, jako instrukcje wyliczajce wartoci, które nigdy nie zostan wykorzystane 60
usuwanie kodu martwego wynikiem propagacji kopii czsto jest to, e instrukcje kopiowania s przekształcane w kod martwy propagacja kopii, a nastpnie eliminacja kodu martwego usuwa przypisanie do x i pozostawia w bloku B5 kod: 61
usuwanie kodu martwego podobnie, stwierdzenia podczas kompilacji, e warto wyraenia jest stała, pozwala zastpi wyraenie przez stał nazywa si to zwijaniem (do) stałych 62
optymalizacje ptli czas działania programu mona zmniejszy, jeeli zmniejszy si liczb instrukcji w ptli wewntrznej, nawet zwikszajc kod na zewntrz ptli ptle s rozpatrywane od wewntrznych do zewntrznych 63
optymalizacje ptli techniki optymalizacji ptli: przemieszczenie kodu eliminacja zmiennych indukcyjnych redukcja mocy 64
przemieszczenie kodu przekształcenie to pobiera wyraenie, zwracajce tak sam warto, niezalenie od iloci wykona ptli, i umieszcza je przed ptl obliczenie niezmiennicze, ze wzgldu na ptle 65
przemieszczenie kodu wynikiem przemieszczenia kodu jest: 66
eliminacja zmiennych indukcyjnych jeeli warto jednej zmiennej pozostaje w okrelonej relacji z wartoci drugiej zmiennej, to s to zmienne indukcyjne w bloku B3 jeeli warto zmiennej j zmniejsza si o 1, to warto zmiennej t4 zmniejsza si o 4 jeeli w ptli s dwie zmienne indukcyjne lub wicej, mona usun wszystkie oprócz jednej 67
eliminacja zmiennych indukcyjnych jeeli w ptli s dwie zmienne indukcyjne lub wicej, mona usun wszystkie oprócz jednej moemy zastpit4 := 4*j przez t4 := t4-4 zalenot4 := 4*j musi by spełniona przy wejciu do B3, std rozszerzenie B1 68
eliminacja zmiennych indukcyjnych eliminacja zmiennych indukcyjnych skutkuje tzw. redukcj mocy tutaj zastosowano redukcj mocy do 4*j w bloku B3 69
redukcja mocy 70
redukcja mocy po zastosowaniu redukcji mocy do ptli wokół bloków B2 i B3, i i j słu jedynie do testu w bloku B4 poniewat2 = 4*i, a t4 = 4*j, std test t2 >= t4 to to samo co i >= j wtedy i w bloku B2 i j w bloku B3 s martwe i przypisania do nich mona usun 71
graf przepływu po usuniciu zmiennych indukcyjnych 72
graf przepływu po usuniciu zmiennych indukcyjnych liczba instrukcji w blokach B2 i B3 zmniejszyła si z 4 do 3, w bloku B5 z 9 do 5, w bloku B6 z 8 do 3 liczba instrukcji w bloku B4 pozostała taka sama (1) bloki B2, B3, B4 i B5 to ptla zewntrzna liczba instrukcji w bloku B1 wzrosła z 4 do 6 (wykonane tylko raz) 73
uwagi kocowe na koniec przypomnimy rady dotyczce zwikszenia wydajnoci programu, podane w pracy [Kernigham1999]: zlokalizuj w programie wskie gardła (na przykład dlaczego program wykrywajcy spam nie radzi sobie z analiz przychodzcej poczty) 74
uwagi kocowe dalsze rady [Kernigham1999]: zanim przyspieszysz program, pomierz jego czas wykonania i uyj profilatora wykonaj pomiary czasu i profilowanie programu (automatyzuj pomiary czasu, korzystaj z profilatorów, skoncentruj si na gorcych miejscach - popraw algorytm realizujcy funkcj albo napisz nowy program, narysuj obrazek pokazujcy wykres wpływu zmian na przyspieszenie programu) 75
uwagi kocowe dalsze rady [Kernigham1999]: uyj lepszego algorytmu lub innej struktury danych włcz optymalizowanie przez kompilator nie optymalizuj tego, co bez znaczenia 76
uwagi kocowe dalsze rady [Kernigham1999]: dostrój kod (gromad wspólne podwyraenia, kosztowne operacje zastp taszymi, rozwijaj lub usuwaj ptle, czsto uywane wartoci przechowuj w pamici podrcznej, napisz specjaln funkcj przydzielania pamici, uywaj buforowanego wejcia i wyjcia, specjalne przypadki obsługuj oddzielnie, korzystaj z wczeniej obliczonych wyników, uywaj wartoci przyblionych, napisz fragment od nowa w jzyku niszego poziomu) 77
uwagi kocowe dalsze rady [Kernigham1999]: oszczdzaj pami (uywaj jak najmniejszych typów danych, nie odsyłaj do pamici tego co mona łatwo ponownie obliczy) oszacuj czas poszczególnych instrukcji jzyka albo rozkazów maszyny, stwórz model kosztów dla jzyka lub systemu 78