Top Banner
orlesung, Wintersemester 2009/10 M. Schölzel Optimierungstechniken in modernen Compilern Einführung
24

Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

Apr 05, 2015

Download

Documents

Fritzi Gerst
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

1

Vorlesung, Wintersemester 2009/10 M. Schölzel

Optimierungstechniken in modernen Compilern

Einführung

Page 2: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

2Optimierungstechniken in modernen Compilern Einführung

Klassifizierung von Computersystemen

Klassifizierung nach Flynn:

Single Instruction Single Data (SISD): Ein einzelner Prozessor führt einen Befehlsstrom auf Daten in einem

Datenspeicher aus.

Multiple Instruction Single Data (MISD): Eine Sequenz von Daten aus

demselben Speicher wird von mehreren Ausführungseinheiten bearbeitet, von denen jede einen

eigenen Steuerfluss besitzt.

Single Instruction Multiple Data (SIMD): Ein einzelner Befehl steuert mehrere Ausführungseinheiten, von denen jede Zugriff auf einen lokalen

Speicher hat.

Multiple Instruction Multiple Data (MIMD): Mehrere Steuerflüsse

steuern mehrere Ausführungseinheiten, von denen jede

Zugriff auf einen lokalen Speicher hat.

Es

exis

tier

t ei

n

Ste

uer

flu

ss i

m

Pro

gra

mm

.

Es

exis

tier

en

meh

rere

S

teu

erfl

üss

e im

P

rog

ram

m.

Alle Ausführungseinheiten greifen auf denselben

Datenspeicher zu.

Jede Ausführungseinheiten besitzt einen lokalen

Datenspeicher (z.B. einen Cache).

Page 3: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

3Optimierungstechniken in modernen Compilern Einführung

Einordnung von Prozessorarchitekturen

Prozessororganisation

SISD SIMD MISD MIMD

Shared Memory

Distributed Memory

ClusterSymmetric Multiprocessor

(SMP)

Non-UniformMemory Access

(NUMA)

Vector Processor

Array Processor

Uniprocessor

Scalar Superscalar

Dynamic Scheduled

Static Scheduled

Static AllocationDynamic Allocation

i386, i486

Pentium

VLIW: Transmeta Crusoe, Philips

TriMedia

GeclusterteVLIWs

Dual-Core Pentium

Itanium

TMS320C62x

Page 4: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

4Optimierungstechniken in modernen Compilern Einführung

Skalarer Prozessor ohne Pipeline

Typische Optimierungen des Compilers: Registerdruck minimieren Geeigneten Zielcode auswählen

Ste

ue

rwe

rk

Registerbank

ALU

Speicher

ldm (r8) r0

ldm (r9) r1

ldm (r10) r2

add r0,r1 r0

add r0,r2 r0

use r8,r9,r10

ldm (r8) r0

ldm (r9) r1

add r0,r1 r0

ldm (r10) r1

add r0,r1 r0

use r8,r9,r10

ldc #8 r0

add r0,r8 r0

ldm (r0) r1

ldm (r8+8) r1

Speicher

Speicher

Schematischer Aufbau:Hoher Registerdruck: Geringer Registerdruck:

Schlechte Codeauswahl: Bessere Codeauswahl:

Page 5: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

5Optimierungstechniken in modernen Compilern Einführung

Skalarer Prozessor mit Befehlspipeline

Typische Optimierungen des Compilers: Registerdruck minimieren Geeigneten Zielcode auswählen Pipeline-Hazards vermeiden

Registerbank

ALU

Speicher

FE/DE

Speicher

DE/EX

EX/MEM

Ste

ue

rwe

rk

MMU

MEM/WB

ldm (r8) r0

ldm (r9) r1

stall

stall

add r0,r1 r0

ldm (r10) r2

stall

stall

add r0,r2 r0

ldm (r8) r0

ldm (r9) r1

ldm (r10) r2

stall

add r0,r1 r0

stall

stall

add r0,r1 r0

Schematischer Aufbau:Schlechte Befehlsanordnung:

Bessere Befehlsanordnung:

Page 6: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

6Optimierungstechniken in modernen Compilern Einführung

Superskalarer Prozessor

Typische Optimierungen des Compilers: Registerdruck minimieren Geeigneten Zielcode auswählen Umordnung der Operationen, um Abhängigkeiten zwischen Operationen im Befehlspuffer

zu minimieren.

Registerbank

ALU Speicher

DE1/DE2

DE2/EX

EX/MEM

Ste

ue

rwe

rk

MMUALU

FE/DE1

Speicher

Befehlspuffer

add r0,r1 r2

add r0,r2 r2

add r0,r3 r4

add r0,r4 r4

add r0,r1 r2

add r0,r3 r4

add r0,r2 r2

add r0,r4 r4

Schlechte Befehls-anordnung für Puffer mit Kapazität 2:

Schematischer Aufbau:

Bessere Befehls-anordnung für Puffer mit Kapazität 2:

Page 7: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

7Optimierungstechniken in modernen Compilern Einführung

VLIW

Typische Optimierungen des Compilers: Registerdruck minimieren Geeigneten Zielcode auswählen Pipeline-Hazards vermeiden Feingranulare Parallelität erkennen und Operationen statisch

parallelisieren.

Registerbank

ALU Speicher

FE/DE

DE/EX

EX/MEM

Ste

ue

rwe

rk

MMUALU

Speicheradd r0,r1 r2

add r0,r2 r2

add r0,r3 r4

add r0,r4 r4

add r0,r1 r2 | add r0,r3 r4

add r0,r2 r2 | add r0,r4 r4

Schematischer Aufbau: Sequentieller Programmcode:

Parallelisierter Programmcode:

Page 8: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

8Optimierungstechniken in modernen Compilern Einführung

SMP

Typische Optimierungen: Grobgranulare Parallelität erkennen und das Programm in Threads aufteilen,

so dass wenig Synchronisation zwischen den Threads erforderlich ist. Registerdruck minimieren Geeigneten Zielcode auswählen Pipeline-Hazards vermeiden

call f

call gcall f

Registerbank

ALU

FE/DESpeicher

DE/EX

EX/MEM

Steu

erw

erk

MMU

MEM/WB

Registerbank

ALU

FE/DESpeicher

DE/EX

EX/MEM

Steu

erw

erk

MMU

MEM/WB

Bus

ldc #100 r0

loopHead:

dec r0

cmp r0,#0

jnz loopHead

ldc 100 r0

loopHead:

dec r0

cmp r0,#50

jg loopHead

ldc 50 r0

loopHead:

dec r0

cmp r0,#0

jnz r0 loopHead

Cache Cache

gemeinsamer Speicher

Schematischer Aufbau: Sequentieller Code: Code Proc1: Code Proc2:

call g

Sequentieller Code: Code Proc1: Code Proc2:

Page 9: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

9Optimierungstechniken in modernen Compilern Einführung

Warum soll der Compiler optimieren?

Optimierungen auf Quelltextebene (z.B. durch den Programmierer) sind möglich, machen es aber erforderlich, dass der Quelltext für jede Zielarchitektur optimiert wird.

Verschiedene Optimierungen, die auf Zielcodeebene erforderlich sind, lassen sich in einer Hochsprache nicht formulieren (z.B. Registerplanung):

Statisch geplante Architekturen:• Compiler führt Scheduling und Allokation durch – auf Quelltextebene in der

Regel nicht ausdrückbar Dynamisch geplante bzw. skalare Architekturen

• Compiler kann Hazards vermeiden helfen und Pipeline besser füllen• Nur ein kleines Fenster für die Optimierung in Hardware; Compiler kann

optimierbaren Code in dieses Fenster schieben SMP

• Compiler verteilt Programmcode und macht Parallelisierung möglich Programmiersprachen besitzen sequentielle Semantik; Geeignete

Form der Parallelität muss durch den Compiler erkannt werden: feingranular, grobgranular.

Page 10: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

10Optimierungstechniken in modernen Compilern Einführung

Demonstration dieser Problematik an einem Beispiel: Matrixmultiplikation

Optimal für eine skalare Architektur. Ergebnis der Multiplikation wird im Register für t akkumuliert.

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t = 0.0; for k = 1 to 100 step 1 do t = t + a[j][k] * b[k][i] od c[j][i] = t; odod

i = 1iLoop: j = 1jLoop: t = 0.0; k = 1kLoop: t = t + a[j][k] * b[k][i] k = k + 1 if k <= 100 then goto kLoop c[j][i] = t; j = j + 1 if j <= 100 then goto jLoop i = i + 1; if i <= 100 then goto iLoop

Page 11: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

11Optimierungstechniken in modernen Compilern Einführung

Was kann parallel ausgeführt werden?

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t = 0.0; for k = 1 to 100 step 1 do t = t + a[j][k] * b[k][i] od c[j][i] = t; odod

Basisblock enthält keine nennenswerte Parallelität

Iterationen der k-Schleife können nicht parallel ausgeführt werden: Iteration k+1 benötigt Wert von t aus Iteration k.

Iterationen der j-Schleife können nicht parallel ausgeführt werden: Benutzung derselben Variablen t.

Iterationen der i-Schleife können nicht parallel ausgeführt werden: Benutzung derselben Variablen t.

b

a cj

k

k

i

t

Page 12: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

12Optimierungstechniken in modernen Compilern Einführung

t

Scalar Expansion

Basisblock enthält keine nennenswerte Parallelität

Iterationen der k-Schleife können nicht parallel ausgeführt werden: Iteration k+1 benötigt Wert t[j] aus Iteration k.

Iterationen der j-Schleife können parallel ausgeführt werden, weil a und b nur gelesen werden und Akkumulation in unterschiedliche Elemente von t erfolgt.

Iterationen der i-Schleife können nicht parallel ausgeführt werden: Benutzung derselben Variablen t.

b

a cj

k

k

i

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = 0.0; for k = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] od c[j][i] = t[j]; odod

t[j]

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t = 0.0; for k = 1 to 100 step 1 do t = t + a[j][k] * b[k][i] od c[j][i] = t; odod

Page 13: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

13Optimierungstechniken in modernen Compilern Einführung

Loop-Distribution

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = 0.0; od for j = 1 to 100 step 1 do for k = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] od od for j = 1 to 100 step 1 do c[j][i] = t[j]; odod

t

b

a cj

k

k

i

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = 0.0; for k = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] od c[j][i] = t[j]; odod

Zuerst Vektor t initialisieren.

Werte in t berechnen.

Werte aus t nach c zurück schreiben.

Initialisieren, Berechnen und Zurückschreiben wurde separiert; kann aber nicht parallel ausgeführt werden.

Initialisieren, Berechnen und Zurückschreiben geschieht Elementweise in t.

Page 14: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

14Optimierungstechniken in modernen Compilern Einführung

Loop-Interchange

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = 0.0; od for k = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] od od for j = 1 to 100 step 1 do c[j][i] = t[j]; odod

t

b

a cj

k

k

i

Iterationen der inneren Schleife können parallel ausgeführt werden.

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = 0.0; od for j = 1 to 100 step 1 do for k = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] od od for j = 1 to 100 step 1 do c[j][i] = t[j]; odod

Keine nennenswerte Parallelität in der inneren Schleife, da jede Iteration den Wert t[j] aus der vorigen Iteration benötigt.

Page 15: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

15Optimierungstechniken in modernen Compilern Einführung

Möglichkeit der Vektorisierung (idealisiert)

for i = 1 to 100 step 1 do t[1..100] = 0.0; for k = 1 to 100 step 1 do t[1..100] = t[1..100]+a[1..100][k]*b[k][i] od c[1..100][i] = t[1..100];od

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = 0.0; od for k = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] od od for j = 1 to 100 step 1 do c[j][i] = t[j]; odod

t

b

a cj

k

k

i

Vektoroperation erfordert die parallele Ausführbarkeit der Operationen auf den Elemente des Vektors. Damit sind diese Operationen parallel auf einem superskalaren nicht-Vektor Prozessor ausführbar.

Page 16: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

16Optimierungstechniken in modernen Compilern Einführung

Möglichkeit der Vektorisierung (praktisch)

for i = 1 to 100 step 1 do t[1..100] = 0.0; for k = 1 to 100 step 1 do t[1..100] = t[1..100]+a[1..100][k]*b[k][i] od c[1..100][i] = t[1..100];od

for i = 1 to 100 step 1 do for j = 1 to 100 step 32 do t[j..j+31] = 0.0; od for k = 1 to 100 step 1 do for j = 1 to 100 step 32 do t[j..j+31] = t[j..j+31]+a[j..j+31][k]*b[k][i] od od for j = 1 to 100 step 32 do c[j..j+31][i] = t[j..j+31]; odod

t

b

a cj

k

k

i

Page 17: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

17Optimierungstechniken in modernen Compilern Einführung

Ausführung auf VLIW-Prozessor mit N Ausführungseinheiten

for i = 1 to 100 step 1 do for j = 1 to 100 step N do t[j] = 0.0; ... ; t[j+N-1] = 0.0; od for k = 1 to 100 step 1 do for j = 1 to 100 step N do t[j] = t[j]+a[j][k]*b[k][i]; ... t[j+N-1] = t[j+N-1]+a[j+N-1][k]*b[k][i]; od od for j = 1 to 100 step N do c[j][i] = t[j]; ... c[j+N-1][i] = t[j+N-1]; odod

N Multiplikationen und Additionen können parallel ausgeführt werden.

for i = 1 to 100 step 1 do for j = 1 to 100 step 32 do t[j..j+31] = 0.0; od for k = 1 to 100 step 1 do for j = 1 to 100 step 32 do t[j..j+31] = t[j..j+31]+a[j..j+31][k]*b[k][i] od od for j = 1 to 100 step 32 do c[j..j+31][i] = t[j..j+31]; odod

Page 18: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

18Optimierungstechniken in modernen Compilern Einführung

t1

Matrixmultiplikation für SMP mit zwei Prozessoren

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t = 0.0; for k = 1 to 100 step 1 do t = t + a[j][k] * b[k][i] od c[j][i] = t; odod

for i = 1 to 50 step 1 do for j = 1 to 100 step 1 do t0 = 0.0; for k = 1 to 100 step 1 do t0 = t0 + a[j][k] * b[k][i] od c[j][i] = t0; odod

for i = 51 to 100 step 1 do for j = 1 to 100 step 1 do t1 = 0.0; for k = 1 to 100 step 1 do t1 = t1 + a[j][k] * b[k][i] od c[j][i] = t1; odod

t0

b

aj

k

k

i

Page 19: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

19Optimierungstechniken in modernen Compilern Einführung

Grob- vs. feingranulare Parallelität

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = 0.0; od for j = 1 to 100 step 1 do for k = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] od od for j = 1 to 100 step 1 do c[j][i] = t[j]; odod t

b

a cj

k

k

iMatrixmultiplikation vor Loop-Interchange (keine feingranulare Parallelität in der inneren Schleife):

for j = 1 to 50 step 1 do for k = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] odod

for j = 51 to 100 step 1 do for k = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] odod

Aber äußere Schleife kann auf zwei verschiedenen Prozessoren verteilt werden.

t[j]

Page 20: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

20Optimierungstechniken in modernen Compilern Einführung

Grob- vs. feingranulare Parallelität

for i = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = 0.0; od for k = 1 to 100 step 1 do for j = 1 to 100 step 1 do t[j] = t[j]+a[j][k]*b[k][i] od od for j = 1 to 100 step 1 do c[j][i] = t[j]; odod t

b

a cj

k

k

i

Aufteilen der äußeren Schleife auf verschiedene Prozessoren führt zu gleichzeitigem Schreiben derselben Elemente in t. Ist also nicht möglich.

Matrixmultiplikation nach Loop-Interchange (viel feingranulare Parallelität in der inneren Schleife):

Page 21: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

21Optimierungstechniken in modernen Compilern Einführung

Aufgeworfene Fragen

Unter welchen Umständen ist eine bestimmte Transformation zulässig?

Welche Transformationen erzeugen fein granulare Parallelität, grob granulare Parallelität?

Wie kann die erzeugte fein granulare Parallelität in superskalaren Prozessorarchitekturen genutzt werden?

Wie kann die erzeugte grob granulare Parallelität in SMP Architekturen genutzt werden?

Page 22: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

22Optimierungstechniken in modernen Compilern Einführung

Aufbau der Vorlesung

Einleitung Grundlagen

Aufbau eines Compilers Überblick über die Analysephase Vorgehen bei einfacher Synthesephase Zwischencodeformate Datenflussanalyseschema Modellierung von Datenabhängigkeiten Abhängigkeitsanalyse

Page 23: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

23Optimierungstechniken in modernen Compilern Einführung

Aufbau der Vorlesung

Optimierungstechniken für DSPs und Mikrocontroller Globale Registerallokation Scheduling-Techniken Code-Selektion

Optimierunbgstechniken für superskalare Prozessoren Erzeugung fein granularer Parallelität Trade-Off Registerallokation/ILP Statische/Dynamische Parallelisierung HW-Support für bessere statische Parallelisierung Region-Based-Scheduling Global Code Motion Traces, Superblöcke, Hyperblöcke Modulo Scheduling IF-Conversion

Page 24: Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Einführung.

24Optimierungstechniken in modernen Compilern Einführung

Aufbau der Vorlesung

Optimierungstechniken für SMPs Erzeugung grob granularer Parallelität Parallelisierung ohne Synchronisierung Parallelisierung mit Synchronisierung (OpenMP)