1 / 36

Code-Optimierung

Code-Optimierung. Philipp Bergener Seminar „Übersetzung künstlicher Sprachen“. Agenda. Einführung Grundlagen Datenflussanalyse Methoden zur Code-Optimierung Zusammenfassung. Ziele und Anforderungen. Verbesserung des Codes, der bei direkter, „naiver“ Übersetzung entsteht

rasha
Download Presentation

Code-Optimierung

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Code-Optimierung Philipp Bergener Seminar „Übersetzung künstlicher Sprachen“

  2. Agenda • Einführung • Grundlagen • Datenflussanalyse • Methoden zur Code-Optimierung • Zusammenfassung

  3. Ziele und Anforderungen • Verbesserung des Codes, der bei direkter, „naiver“ Übersetzung entsteht • Optimierungsmöglichkeiten • Verbesserung der Ausführgeschwindigkeit • Verringerung des Speicherbedarfs zur Laufzeit • Verkleinerung des erzeugten Codes • Anforderungen • Semantik des Programms muss erhalten bleiben • Aufwand für Optimierung muss sich lohnen

  4. Systematisierung • Nach Zeitpunkt für Code-Optimierung: • Nach Zwischen-Codeerzeugung: Eher allgemeine Methoden • Nach Maschinen-Codeerzeugung: Eher maschinenspezifisch • Globale vs. lokale Optimierung • Lokal: Nur Ausschnitt (Basisblock) wird betrachtet • Global: Mehrere Basisblöcke werden betrachtet

  5. Agenda • Einführung • Grundlagen • Datenflussanalyse • Methoden zur Code-Optimierung • Zusammenfassung

  6. Drei-Adress-Code • Zur Darstellung des Zwischencodes • Maximal 3 Adressen pro Befehl • Typen von Befehlen • Zuweisung: x = y op z op: arithmetisch (+,-,*,/) oder logisch (AND, OR) • Kopieranweisungen: x = y • Unbedingte Sprünge: goto L (L Sprungmarke) • Bedingte Sprünge: if x goto L bzw. ifFalse x goto L oder if x relop y bzw. ifFalse x relop y (relop: <, ==, >, etc.) • Indizierte Kopieranweisungen: x = a[i] bzw. a[i] = xa[i]: Speicherstelle i Einheiten hinter a

  7. Basisblöcke und Flussgraphen Basisblöcke • Strukturieren den Code • Eigenschaften eines Basisblocks: • Kann nur durch die erste Anweisung betreten werden • Wird ohne Sprünge durchlaufen. Sprünge nur in der letzten Anweisung • Ein Basisblock beginnt • Bei der ersten Codezeile • Bei Zeilen, die Ziel von Sprüngen sind • Bei Zeilen, die auf Sprünge folgen Flussgraphen • stellen Kontrollfluss grafisch dar • Basisblöcke sind Knoten • 2 zusätzliche Knoten Eingang und Ausgang

  8. Beispiel: Binäre Suche Eingang publicIngeger binsearch(Integer k) { Integer m,l,r; //Anfang l = 0; r = N-1; do{ m = (l+r)/2; if(k < a[m]) r = m-1; else l = m+1; while((k != a[m])||(l<r)); //Ende ... end B1 l = 0 r = N-1 B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B4 l = m+1 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 B6 if l<r goto B2 Ausgang

  9. Agenda • Einführung • Grundlagen • Datenflussanalyse • Methoden zur Code-Optimierung • Zusammenfassung

  10. Datenflussanalyse • Viele Optimierungsansätze brauchen Informationen über Datenfluss im Programm • Programm ist eine Folge von Zuständen • Zustand: unter anderem aktuelle Werte der Variablen • Anweisungen sind Zustandsübergänge • Durch Sprünge sind Zustände nicht immer eindeutig • Nur der für ein Problem relevante Teil des Zustandes betrachtet • Es wird nicht unterschieden auf welchem Pfad ein Programmpunkt erreicht wird

  11. Bestandteile eines Datenflussproblems • Datenflussproblem ist 4-Tupel (D, V, ^, F) • Datenflussrichtung D  {Vorwärts, Rückwärts} • Gibt an ob Informationen mit oder gegen Informationsfluss fließen • Domäne V • relevanter Teil des Zustandes • Konfluenzoperator ^ (z.B. ) • Zum Übergang zwischen Blöcken • Menge von Transferfunktionen F • F: V  V • Für ganze Basisblöcke

  12. Verfügbare Definitionen • Fragestellung: Welche Definition für eine Variable ist an einem bestimmten Programmpunkt gültig • Datenflussrichtung: D = Vorwärts • Domäne: Potenzmenge der Menge aller Definitionen • Konfluenzoperator: , also IN[B] = P Vorgänger von BOUT[P] • Transferfunktion: • genB: Menge generierter Definitionen in Block B • killB: Menge gelöschter Definitionen in Block B • Dann OUT[B] = genB (IN[B] - killB)

  13. Verfügbare Definitionen ... gen[B1]={d1, d2} kill[B1]={d7,d8} B1 l = 0 (d1) r = N-1 (d2) B2 ... B3 gen[B3]={d7} kill[B3]={d2} r = m-1 (d7) goto B5 B4 gen[B4]={d8} kill[B4]={d1} l = m+1 (d8) ...

  14. Aktive Variablen • Eine Variable x ist aktiv an Punkt p, wenn der Wert von x in p entlang eines Pfades von p an benutzt kann und wird. Andernfalls ist sie passiv. • Datenflussrichtung: D = Rückwärts • Domäne: Potenzmenge der Menge aller Variablen • Konfluenzoperator: , also OUT[B] = P Nachfolger von BIN[P] • Transferfunktion: • defB: Menge der Variablen, die in Block B definiert werden • useB: Menge der Variablen, die in B benutzt werden (bevor sie neu definiert werden) • Dann: IN[B] = useB (OUT[B] - defB)

  15. Verfügbare Ausdrücke • Ein Ausdruck der Form x op y ist an einem Punkt pverfügbar, wenn der Ausdruck auf jedem Pfad zu p berechnet wird und weder x noch y danach überschrieben werden • Datenflussrichtung: D= Vorwärts • Domäne: Potenzmenge der Menge aller Ausdrücke • Konfluenzoperator:  also IN[B] =  P Vorgänger von BOUT[P] • Transferfunktion: • e_genB: Menge aller Ausdrücke, die in B (neu) berechnet werden • e_killB: Menge aller Ausdrücke, die in B ungültig werden • Dann: OUT[B] = e_genB (IN[B] - e_killB)

  16. Halbverband • Ein Datenflussproblem bildet einen Halbverband • Eigenschaften eines Halbverbands: • x ^ x = x • x ^ y = y ^ x • x ^ (y ^ z) = (x ^ y) ^ z x, y, z V • Halbverbände haben oberstes Element T mit • T ^ x = x  x V • Für: T =  • Für : T = Basismenge der Potenzmenge

  17. Algorithmus zum Lösen von Datenflussproblemen • Zusätzlich noch Startmenge v (meist ) OUT[Eingang]=vEingang; for(jeden Block B außer Eingang) OUT[B] = T; while(min. ein OUT wird geändert) for(jeden Block B außer Eingang) { IN[B]=^P Vorgänger von pOUT[P]; OUT[B]=fB(IN[B]); } • Für D = Rückwärts • IN und OUT vertauschen • Ausgang statt Eingang

  18. Agenda • Einführung • Grundlagen • Datenflussanalyse • Methoden zur Code-Optimierung • Zusammenfassung

  19. Eliminierung gemeinsamer Teilausdrücke • Gemeinsamer Teilausdruck: Vorkommen von Ausdruck E der schon einmal berechnet wurde und sich nicht mehr geändert hat. • Ziel: wiederholte Berechnungen des gleichen Ausdrucks vermeiden • Ermitteln mit Verfügbaren Ausdrücken • Eliminierung • Teilausdruck in Hilfsvariable speichern • Dann statt Teilausdruck Hilfsvariable verwenden

  20. Eliminierung gemeinsamer Teilausdrücke ... B2 ... t1 = l+r m = t1/2 h1 = 8*m t2 = h1 t3 = a[t2] ifFalse k<t3 goto B4 B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 B4 B3 B4 r = m-1 goto B5 r = m-1 goto B5 l = m+1 l = m+1 B5 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 t4 = h1 t5 = a[t4] ifFalse k==t5 goto B2 ... ...

  21. Weitergabe von Kopien • Durch andere Optimierungsverfahren entstehen Kopien der Form x = y • Ziel: y anstelle von x benutzen • Dadurch kann die Kopieranweisung überflüssig werden • Lösung mit Verfügbaren Definitionen: • Ersetzung ist in p möglich,wenn x und y noch gleichen Wert besitzen • Dazu müssen sowohl die Definition x = yals auch die Definition für y, diein x = y galt, gültig in p sein • Außerdem dürfen keine anderen Definitionen x und yp erreichen

  22. Weitergabe von Kopien ... ... B2 B2 t1 = l+r m = t1/2 h1 = 8*m t2 = h1 t3 = a[t2] ifFalse k<t3 goto B4 t1 = l+r m = t1/2 h1 = 8*m t2 = h1 t3 = a[h1] ifFalse k<t3 goto B4 B3 B3 B4 B4 r = m-1 goto B5 r = m-1 goto B5 l = m+1 l = m+1 B5 B5 t4 = h1 t5 = a[t4] ifFalse k==t5 goto B2 t4 = h1 t5 = a[h1] ifFalse k==t5 goto B2 ... ...

  23. Eliminierung von totem Code • Toter Code: • Anweisungen, die nie erreicht werden • Zuweisungen, die nie benutzt werden • Entsteht durch andere Optimierungen oder (selten) durch Programmierfehler • Identifizierung über aktive Variablen • Beispiel: x = true ... //Hier keine Zuweisungen an x if x goto L1 a = b + c//Toter Code L1: b = 2 * c

  24. Optimierung von Schleifen • Programme verbringen einen Großteil ihrer Zeit in Schleifen • Optimierung von Schleifen daher besonders wichtig • 2 Ansätze zur Optimierung von Schleifen • Export schleifeninvarianter Variablen • Eliminierung von Induktionsvariablen

  25. Optimierung von Schleifen Identifikation von Schleifen • Dominator: Knoten d dominiert Knoten n (d dom n), wenn jeder Pfad im Flussgraph von Eingang zu n über d führt • Rückwärtskante: Kante n → d mit d dom n • Natürliche Schleife einer Rückwärtskante n → d:Alle Knoten von denen n erreicht werden kann ohne durch d zu laufen

  26. Optimierung von Schleifen Eingang B1 l = 0 r = N-1 B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B4 l = m+1 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 B6 if l<r goto B2 Ausgang

  27. Optimierung von Schleifen Eingang B1 l = 0 r = N-1 B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B4 l = m+1 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 B6 if l<r goto B2 Ausgang

  28. Optimierung von Schleifen Eingang B1 l = 0 r = N-1 B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B4 l = m+1 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 B6 if l<r goto B2 Ausgang

  29. Optimierung von Schleifen Export schleifeninvarianter Variablen: • Variable ist schleifeninvariant, wenn in Schleife keine Zuweisung an sie erfolgt • Ein Ausdruck ist schleifeninvariant, wenn er nur aus schleifeninvarianten Variablen besteht • Diese sollen aus der Schleife herausgezogen werden while (i < max) do x := 3*y//3*y ist schleifeninvariant z := x+j j := i*2 i := i+1 end

  30. Optimierung von Schleifen Eliminierung von Induktionsvariablen • Induktionsvariable, die sich bei jedem Schleifendurchlauf um den gleichen, konstanten Wert ändert • Diese sollen (bis auf eine) eliminiert werden x := 3*y x := 3*y while (i < max) doj := 2*i z := x+j while (j < 2*max) do j := i*2 z := x+j i := i+1j := j+2 endend i := max

  31. Konstantenfaltung • Konstanten verbessern die Lesbarkeit von Programmen • Auf Ebenen des Zwischencodes nicht nötig • Daher: Variablen, die an einer Stelle immer den gleichen Wert haben durch diesen ersetzen • Ausdrücke, die nur aus Konstanten bestehen, können dann ebenfalls berechnet werden • Ermittlung von Konstanten auch mit Datenflussanalyse möglich

  32. Konstantenfaltung • Beispiel: N = 10 //Konstante ... x = 2 //Wert in nächster Anweisung immer gleich y = N*x //N und x können ersetzt werden N = 10 ... x = 2 y = 10*2 //Ausdruck kann jetzt berechnet werden

  33. Algebraische Umformungen • Ersetzen von langsameren Befehlen durch schnellere • Ausnutzen von mathematischen Gesetzen • Beispiele • x*2n→ x shiftl n • x + 0 oder x * 1 → x • x2→ x*x • 2*x → x+x • x/4 → x * 0,25

  34. Agenda • Einführung • Grundlagen • Datenflussanalyse • Methoden zur Code-Optimierung • Zusammenfassung

  35. Zusammenfassung • Direkt übersetzter Code kann noch weiter optimiert werden • Es gibt verschiedene Ansätze zur Optimierung • Datenflussanalyse bildet eine wichtige Grundlage für viele dieser Ansätze • Es gibt weitere Optimierungsmethoden, z.B. • für Maschinen-Code • für OO-Sprachen

  36. Fragen Vielen Dank für die Aufmerksamkeit Fragen?

More Related