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