Transparente Nutzung von Multi-GPU Cluster
unter Java/OpenMP
Dipl. Inf. Thorsten Blaß
Programming Systems Group • Martensstraße 3 • 91058 Erlangen
Ausblick
Motivation
Einführung
□ Java/OpenMP (JaMP)
□ JaMP Sprache
Architektur
□ Compute Device Architecture
□ Cluster Array Package
□ Optimierungen
Leistung des Frameworks
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 2
Motivation
Heutige Desktop-PCs sind heterogene parallele Architekturen
Viele Sprachen/Erweiterungen führen ans Ziel
□ nVidia: CUDA, ATI: Stream, Khronos: OpenCL
□ Sprachen/Erweiterungen müssen erlernt und verstanden werden
Bestehende Algorithmen müssen portiert werden
□ Algorithmen-Entwurf / -Portierung ist teuer und fehleranfällig
Neue Architektur -> beginnt das Spiel von vorne?
Wie kann man diese enorme Rechenleistung transparent an Entwickler
weitergeben?
Ziel: Algorithmen nur einmal implementieren und auf beliebigen
Architekturen mit beliebigen Beschleunigern ausführen
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 3
JaMP
JaMP implementiert das OpenMP-Framework für Java
□ Standard zur Programmierung von Shared-Memory-Systemen
□ OpenMP definiert plattformunabhängige Compiler-Direktiven,
Bibliotheksfunktionen und Umgebungsvariablen
Bewahrt Java's „write once run anywhere“-Ansatz
□ Problem: Zur Übersetzungs-Zeit sind keine Annahmen über die
Zielplattform möglich
□ Alle zur Laufzeit verfügbaren Beschleuniger werden genutzt
Compiler-Direktiven sind in Kommentare gekapselt
//#omp parallel for
for(int i = 0; i < 4096; i++){
A[i] = B[i] + C[i]
}
Modfizierter Eclipse-Java-Compiler übersetzt JaMP-Code
nach Java-Bytecode
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 4
JaMP
Java+OpenMP
Quellcode
Java/OpenMP
Übersetzer
Java Bytecode
+ Annotationen
Java/OpenMP
Class Loader
Abstrakte
Kernels
Methoden
Compute Device
Manager
JVM-JIT
GPU/CPU
Übersetzer
Übersetzungszeit
Laufzeit
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 5
JaMP-Sprache
Der Allokations-Abschnitt
sammelt Informationen
für die Datenverteilung
//#omp alloc_sec_start
//#omp managed(sourceImage)
int[][] sourceImage = new int[height][width];
//#omp managed(dstImage)
int[][] dstImage = new int[height][width];
//#omp alloc_sec_end
Übersetzer ersetzt das
angegebene Array durch eine
Instanz eines Array-Packages
Zwei-dimensionale
//#omp parallel for nest(2)
parallele Schleife
for(int i = 0; i < height; i++){
for(int j = 0; j < width ; j++){
dstImage[i][j] = srcImage[i][j] + Math.sqrt(i);
}
}
Funktionen werden durch eine
an die Hardware angepasste
ersetzt
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 6
Ausblick
Motivation
Einführung
□ Java/OpenMP (JaMP)
□ JaMP Sprache
Architektur
□ Compute Device Architecture
□ Cluster Array Package
□ Optimierungen
Leistung des Frameworks
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 7
JaMP - Architektur
JaMP
Cluster Array Package
Compute Kernel Manager
MPI
Threads OpenCL CUDA
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 8
Compute Kernel Manager (CKM)
API zur generischen Programmierung von Kerneln
Abstrahiert von konkreten Beschleunigern (Device)
□ Speicherverwaltung
□ Generiert aus der CKM Sprache Device spezifische Kernel
□ Ruft Kernel auf einer Menge von Devices auf
Ausmessen der Devices beim Start
□ Gemessen werden: Nachrichten-Transfers, Kernellaufzeiten
□ Ergebnisse werden in Speed-up umgerechnet
Verbirgt MPI und RPCs
□ (entfernte) Kopieroperationen zwischen Devices
□ (entfernte) Übersetzung der Kernels
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 9
Cluster Array Package (CAP)
Verteilt die Daten über die verfügbaren Devices:
□ Stellt Zugriffsmethoden (get/set) zur Verfügung
□ Kopieroperationen
□ Array-Elemente werden in Chunks verwaltet
Chunks werden einzelnen Devices zugeordnet
Drei Array-Typen
□ Repliziertes Array
Sicherstellen der Datenkonsistenz
□ Partitioniertes Array
Datenverteilung auf die verfügbaren Devices
□ Wrapper Array
Verbirgt tatsächlich instantiierten Array-Typ
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 10
Cluster Array Package (CAP) – Repliziertes Array
Wird genutzt bei zufälligen Adressierungsmustern
□ //#omp parallel for
for(int i = 0; i < x; i++){
a[2 * i + 8] = ….
}
Jedes Device erhält eine lokale Kopie des Arrays
□ Alle Chunks enthalten die selben Daten
Datenkonsistenz muss sichergestellt werden
□
□
□
□
Jeder Knoten benötigt einen zusätzlichen Chunk (Urbild)
Device verändert Element → Chunks unterscheiden sich
Erzeugen eines Diff: Vergleiche Chunks gegen lokale Kopie
Aktualisiere alle lokalen Chunks und sende Diffs zu allen anderen Knoten
Jeder Knoten führt die gleichen Operationen aus
□ Übersetzer fügt Anweisungen zur Sicherstellung der Datenkonsistenz
ein
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 11
Cluster Array Package - Partitioniertes Array
Wird verwendet wenn daten-paralleles Rechnen möglich ist
Partitionierungsvektor zur Bestimmung der partitionierbaren Dimensionen
□ //#omp parallel for
for(int i = 0; i < x; i++){
a[i] = ….
}
□ Partitionierungsvektor [1]
//#omp parallel for
for(int i = 0; i < x; i++){
for(int j = 0; j < y; j++){
a[i][2*j+i] = ….
}
}
a[i][2*j+1] Partitionierungsvektor [1,0]
Boundaries helfen, den Kommunikationsaufwand beim Zugriff auf
Nachbarelemente zu reduzieren
□ a[i+1], a[i-1], …
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 12
Cluster Array Package – Partitioniertes Array
Jedes Device erhält nur einen Teilbereich eines Arrays
□ Benötigt Partitionierung-Algorithmus
□ Rechenleistung eines Devices entscheidet über die Größe
der zugeteilten Indexmenge
CAP bietet drei Partitionierungs-Algorithmen
□ Partitionieren nach Rechenleistung
□ Verzögerte Partitionierung
□ Maximale Speicherauslastung
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 13
Cluster Array Package – Partitioniertes Array
Partitionierung nach Rechenleistung
□ Wähle partitionierbare Dimension (Partitionierungsvektor)
□ Aufsummieren aller Speed-ups
□ Summe wird als verfügbare (virtuelle) Devices interpretiert
□ Partitionierbare Dimension wird durch Anzahl der virtuellen
Devices geteilt → virtuelle chunks pro Device
□ Virtuelle Devices werden auf die Realen abgebildet
(konsumierten dabei die virtuellen Chunks)
Partitionierungsvektor [1,1]
Speedup = 1
3 Virtuelle Devices
Speedup = 2
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 14
Cluster Array Package – Partitioniertes Array
Verzögerte Partitionierung
□ Arbeitet wie “Partitionierung nach Speed-up“ berücksichtigt
zusätzlich komplett benötigten Speicher
□ Bevor die Partitionierungs-Informationen berechnet werden,
findet eine Überprüfung statt ob ALLE Arrays in den Speicher
des Devices passen
□ Versucht ein Device mehr virtuelle Chunks zu konsumieren als
in den Speicher passen wird die Größe angepasst
Optimiert für Speicherauslastung
□ Nutzt so wenig Devices wie möglich
□ Devices sind aufsteigend nach ihrem speed-up sortiert
□ Speicher eines Devices wird komplett gefüllt
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 15
Motivation – Adaptive Rekonfiguration
Frage: Wieviele Knoten (und welche Devices) soll ich für mein
Programm benutzen?
Antwort hängt von der Applikation ab:
□ Zuviele Knoten können zu hohen Kommunikationskosten führen
□ Zu wenige Knoten können zu einer Überlastung der Knoten
führen
□ Geeignete Devices hängen von der Komplexität des Kernels ab
Heuristik generiert verschiedene Device-Mengen zu
definierten Zeitpunkten (z.B. jeden n-ten parallelen Aufruf) vor
einem parallelen Aufruf
□ Misst die Zeit, die eine Kernel-Ausführung benötigt
□ Rekonfiguriert Arrays auf neue Device-Menge
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 16
Adaptive Rekonfiguration
Benötigt Heuristik, um zu entscheiden wie/wann neue
Device-Mengen erstellt werden
□ Starte mit einem Knoten und füge nachfolgend neuen hinzu
□ Starte mit allen Knoten und entferne jeweils einen
□ Knoten werden hinzugefügt bzw. entfernt, wenn
der Speed-up unterhalb einer vorgegebenen Schranke
bleibt
das Verhältnis zwischen Laufzeit/KommunikationsAufwand eine bestimmte Schranke überschreitet
Heuristik wird zur Laufzeit ausgewählt
□ Analysiere verfügbare Devices
□ Enthält Device-Menge nur einen Knoten: Hinzufügen
□ Enthält Device-Menge alle Knoten: Entferne
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 17
Adaptive Rekonfiguration
Implementiert in 3 Modulen:
1) Virtueller Cluster
Verwaltet Devices in virtuellen Cluster-Knoten
▫ Gegenwärtig benutze und verfügbare Devices
Heuristik:
▫ Hinzufügen oder entfernen
2) Adaptive Info
Ausgangspunkt für Rekonfiguration
Vergleicht aktuelle Device-Menge gegen bisher Beste
▫ Liefert better, worse, equal zurück
Generiert nächste Device-Menge
Modelliert als endlicher Zustandsautomat
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 18
Adaptive Rekonfiguration
Heuristiken
□ Implementieren Methoden ...
… die entscheiden wie eine Device-Menge in einem
bestimmten Zustand verändert wird
… wie die Device-Menge gebildet wird
□ Definieren, welche Devices berücksichtigt werden sollen
(z.B nur GPUs, nur CPUs, alles)
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 19
Ausblick
Motivation
Einführung
□ Java/OpenMP (JaMP)
□ JaMP Sprache
Architektur
□ Compute Device Architecture
□ Cluster Array Package
□ Optimierungen
Leistung des Frameworks
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 20
Performance
Zusammensetzung der Laufzeit Matrix-Multiplikation
(2048x2048)
1,7 s
Kernellaufzeit
Speichermanagement
Übersetzungszeit
0,3 s
3,7 s
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 21
Speed-up gegenüber einem Knoten mit CPU
CPU
GPUs
CPU + GPU
CPU
350
GPUs
CPU + GPU
CPU
250
300
CPU + GPU
350
300
200
250
200
150
100
150
Sped-up
Speed-up
250
100
50
0
2
4
8
0
1
2
Nodes
4
8
Nodes
Edge Detection
150
50
0
1
200
100
50
CPU
GPUs
1
2
4
Nodes
Matrix Multiplikation 5000x5000
Black Scholes
CPU + GPU
180
160
140
120
Speed-up
Speed-up
GPUs
100
80
60
40
20
0
1
2
4
8
Nodes
Seure Function Evaluation
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 22
8
Zusammenfassung
Java's „write-once-run-everywhere“-Ansatz bleibt erhalten
Anwender parallelisiert einen Algorithmus nicht für eine
spezielle Architektur
Vorhandener Code kann mit minimalen Aufwand parallelisiert
werden
JaMP ermöglicht die transparente Nutzung von
Beschleunigern
JaMP ermöglicht die Nutzung von Clustern ohne zusätzlichen
Aufwand für den Programmierer
JaMP sucht die für einen Algorithmus geeignetste
Kombination von Beschleunigern / Knoten aus
Ausstehende Erweiterungen: Objekte, Exceptions, ...
Transparente Nutzung von Multi-GPU Cluster unter Java/OpenMP • Thorsten Blaß • 06.04.2011 • Folie 23