1 / 32

OpenMP

OpenMP. Präsentation im Rahmen des Seminars „Parallele und verteilte Programmierung“ Michael Westermann. Gliederung. Einführung Vergleich von OpenMPI und MPI Grundlagen Parallelisierung von Programmbereichen Koordination und Synchronisation von Threads Zusammenfassung. Einführung.

unity
Télécharger la présentation

OpenMP

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. OpenMP Präsentation im Rahmen des Seminars „Parallele und verteilte Programmierung“ Michael Westermann

  2. Gliederung • Einführung • Vergleich von OpenMPI und MPI • Grundlagen • Parallelisierung von Programmbereichen • Koordination und Synchronisation von Threads • Zusammenfassung

  3. Einführung • OpenMP: „Open specifications for Multi Processing“ • Spezifikation für parallele Programmierung • Multiprozessor-Systeme • Gemeinsamer Speicher • Möglichkeit, ein Programm schrittweise zu parallelisieren • Compiler-Direktiven, Bibliotheksfunktionen, Umgebungsvariablen • Bindings für C, C++ und Fortran • 1997 für Fortran; 1998 für C/C++ • Aktuelle Version: OpenMP 2.5 (Mai 2005) • Von vielen Soft- und Hardwareherstellern unterstützt (Intel, Sun, Compaq usw.)

  4. Gliederung • Einführung • Vergleich von OpenMPI und MPI • Grundlagen • Parallelisierung von Programmbereichen • Koordination und Synchronisation von Threads • Zusammenfassung

  5. Vergleich OpenMP vs. MPI • OpenMP und MPI können auch kombiniert werden: • MPI verteilt Arbeit auf Multiprozessor-Systeme • OpenMP führt die Arbeit dort parallel aus

  6. Gliederung • Einführung • Vergleich von OpenMPI und MPI • Grundlagen • Gemeinsamer Speicher • Programmiermodell • OpenMP-Direktiven • Parallelisierung von Programmbereichen • Koordination und Synchronisation von Threads • Zusammenfassung

  7. Grundlagen: Gemeinsamer Speicher • Gemeinsamer Speicher • Mehrere Prozessoren • Einheitlicher Adressraum • Verteilter gemeinsamer Speicher • Mehrere Prozessoren • Seitenbasierter, virtueller, gemeinsamerAdressraum • Beide Varianten werden von OpenMP unterstützt

  8. Grundlagen: Programmiermodell • Auf Threads basierend • Ausführungsfäden innerhalb eines Prozesses • Leichtgewichtiger als Prozesse • Gemeinsamer Adressraum, zusätzlich eigener Stack • Kommunikation über gemeinsame Variablen • Fork-join-Prinzip • Master-Thread erzeugt weitere Threads • Parallele Ausführung des Bereichs • Synchronisation der Threads am Ende • Beenden der Slave-Threads

  9. OpenMP-Direktiven • Einbinden der Datei omp.h zu Beginn • Parallelisierung mittels Compiler-Direktiven #pragmaomp<Klausel> • Direktive wird ignoriert, wenn Compiler OpenMP nicht unterstützt • Programm wird seriell ausgeführt • Identischer Quelltext für Ein- und Multiprozessor-System

  10. Gliederung • Einführung • Vergleich von OpenMPI und MPI • Grundlagen • Parallelisierung von Programmbereichen • Parallele Bereiche • Parallelisierung von Schleifen • Parallelisierung unabhängiger Abschnitte • Koordination und Synchronisation von Threads • Zusammenfassung

  11. Parallele Bereiche • parallel-Direktive: #pragmaomp parallel [Parameter [, Parameter]…] { Anweisungsblock } • Grundlegendes Konstrukt • Threads arbeiten Anweisungsblock mit gemeinsamen oder privaten Variablen ab (singleprogram multiple data, SPMD) • Synchronisation am Ende des parallelen Bereichs • Parallele Bereiche können geschachtelt werden • Parameter: • Bestimmung der Thread-Anzahl ( num_threads(x)) • Variablendeklarationen (gemeinsame vs. private Variablen)

  12. Parameter: Variablendeklarationen • shared(<Liste_Variablen>) • Gemeinsame Variablen der Threads  Lesen und Schreiben findet auf gleichem Datenbereich statt • private(<Liste_Variablen>) • Jeder Thread erhält uninitialisierte Kopie der Variablen  Nur der jeweilige Thread kann diese Lesen und Schreiben • default(shared | private | none) • shared: Variablen sind standardmäßig gemeinsam • private: Variablen sind standardmäßig privat • none: Alle Variablen müssen explizit gekennzeichnet werden • Weitere Variablendeklarationen: • firstprivate, lastprivate, copyin, reduction

  13. Parallele Bereiche: Beispiel #include<omp.h> intnummer; intmain() { #pragmaomp parallel private(nummer) num_threads(4) { // Nummer des aktuellen Threads nummer = omp_get_thread_num(); printf("Thread-Nummer: ",nummer); } } Mögliche Ausgabe: Thread-Nummer: 0 Thread-Nummer: 2 Thread-Nummer: 1 Thread-Nummer: 3

  14. Gliederung • Einführung • Vergleich von OpenMPI und MPI • Grundlagen • Parallelisierung von Programmbereichen • Parallele Bereiche • Parallelisierung von Schleifen • Parallelisierung unabhängiger Abschnitte • Koordination und Synchronisation von Threads • Zusammenfassung

  15. Parallelisierung einer for-Schleife Speicher A[1] 4 Prozessoren: for(i=1,i<=25,i++) a[i] = b[i] + c[i] A[100] for(i=26,i<=50,i++) a[i] = b[i] + c[i] B[1] for(i=1,i<=100,i++) a[i] = b[i] + c[i] for(i=51,i<=75,i++) a[i] = b[i] + c[i] B[100] C[1] for(i=76,i<=100,i++) a[i] = b[i] + c[i] C[100]

  16. Parallelisierung einer for-Schleife • Work-Sharing-Konstrukt • Verteilung der Iterationen auf mehrere Threads • Jede Iteration wird von genau einem Thread ausgeführt • for-Direktive: #pragmaompfor[Parameter…] for (Index=Startwert; Test; Inkrementierung) { Schleifenrumpf } • Voraussetzungen: • Iterationen unabhängig voneinander • Anzahl Iterationen vor Ausführung bestimmbar • Innerhalb eines parallelen Bereichs (oder kombinierte Direktive) • #pragmaompparallel for[Parameter…]

  17. Parallelisierung einer for-Schleife for (i=Startwert; Test; Inkrementierung) Anforderungen an Schleifenkopf: • i: Variable vom Typ int • Startwert: x • Test: i op x , mit op { <, ≤, >, ≥ } • Inkrementierung: ++i, --i, i++, i--,i += x, i -= x, i = i + x, i = i - x • x: Schleifenunabhängiger Integer-Ausdruck

  18. Parameter for-Direktive: schedule • Steuert Aufteilung der Iterationen auf die Threads • Lastverteilung • schedule(static, block_size) • Iterationen werden in Blöcke der Größe block_size zusammengefasst • Verteilung der Blöcke auf die Threads bereits vor Ausführung • schedule(dynamic, block_size) • Iterationen werden in Blöcke der Größe block_size zusammengefasst • Nach Bearbeitung eines Blockes erhält Thread neuen Block • schedule(guided, block_size) • Exponentiell abnehmendeBlockgröße im Zeitverlauf • Beispiel: 64 Iterationen, 2 Threads, block_size=4: 1. 64/2=32, 2. 32/2=16, 3. 16/2=8, 4. 8/2=4, 5. 4

  19. Beispiel for-Direktive: Primzahlenausgabe #include<stdio.h> #include <omp.h> intmain() { intzahl, teiler, treffer; printf ("Primzahlen: \n"); #pragmaomp parallel for private(teiler,treffer) \ schedule(dynamic,100) for(zahl = 2; zahl < 100000; zahl++) { treffer = 0; #pragmaomp parallel for private(teiler, treffer) // Überprüfung ob 2 bis zahl Teiler von zahl for(teiler = 2; teiler < zahl; teiler++) { if(zahl % teiler == 0) { treffer = 1; } } if(treffer == 0) { printf ("%d, ", zahl); } } } Mögliche Ausgabe: Primzahlen: 2, 3, 5, 7, 11, 13, 101, 19, 23, 113, 29, […], 99991,

  20. Parameter for-Direktive: ordered • Ausführung erst, wenn alle vorherigen Iterationen den Anweisungsblock beendet haben • ordered-Parameter der for-Direktive hinzufügen • ordered-Direktive vor entsprechenden Anweisungsblock:#pragmaompordered { Anweisungsblock }

  21. Beispiel: Primzahlenausgabe, aufsteigend #include<stdio.h> #include<omp.h> intmain() { intzahl, teiler, treffer; printf ("Primzahlen: \n"); #pragmaomp parallel for private(teiler, treffer) \ schedule(static,1) ordered for(zahl = 2; zahl < 100000; zahl++) { treffer = 0; // Überprüfung ob 2 bis zahl Teiler von zahl for(teiler = 2; teiler < zahl; teiler++) { if(zahl % teiler == 0) { treffer = 1; } } #pragmaompordered if(treffer == 0) { printf ("%d, ", zahl); } } } Ausgabe: Primzahlen: 2, 3, 5, 7, 11, 13, 19, 23, 29, 31, 37, 41, 43, 47, […], 99991,

  22. Gliederung • Einführung • Vergleich von OpenMPI und MPI • Grundlagen • Parallelisierung von Programmbereichen • Parallele Bereiche • Parallelisierung von Schleifen • Parallelisierung unabhängiger Abschnitte • Koordination und Synchronisation von Threads • Zusammenfassung

  23. Parallelisierung unabhängiger Abschnitte • Work-Sharing-Konstrukt • Abschnitte werden auf Threads verteilt • Jeder Abschnitt wird von genau einem Thread ausgeführt • sections-Direktive:#pragma omp sections [ Parameter [, Parameter …] ] { [ #pragma omp section { Anweisungsblock_1 } ] [ #pragma omp section { Anweisungsblock_2 } ] } • Abschnitte müssen unabhängig voneinander sein • section-Direktive nur innerhalb der sections-Direktive

  24. Gliederung • Einführung • Vergleich von OpenMPI und MPI • Grundlagen • Parallelisierung von Programmbereichen • Koordination und Synchronisation von Threads • Kritische Abschnitte • Atomare Operationen • Synchronisation • Ausführung ausschließlich des Master-Threads • Zusammenfassung

  25. RaceConditions • Beispiel: • A = 0 • 2 Threads führen parallel aus: A = A + 1 • Mögliche Ergebnisse: • A = 2 • A = 1 • Ergebnis hängt vom zeitlichen Ablauf der Operationen ab • Lösungsmöglichkeiten: • Kritische Abschnitte • Atomare Operationen

  26. Kritische Abschnitte • Wechselseitiger Ausschluss (mutual exclusion) • Abschnitte werden zu kritischen Abschnitten deklariert • Höchstens ein Thread darf gleichzeitig im kritischen Abschnitt mit gleichem name sein • critical-Direktive:#pragma omp critical [(name)] { kritischer_Abschnitt }

  27. Atomare Operationen • Zuweisung wird „am Stück“ (atomar = unteilbar) ausgeführt • atomic-Direktive:#pragma omp atomic Zuweisung • Zuweisung darf folgende Form haben: • x++, x- - • ++x, - - x • x binop= skalarer_Ausdruck • binop { +, -, *, /, &, ^, |, <<, >> } • skalarer_Ausdruck darf nicht auf x referenzieren und ist nicht Teil der atomaren Operation

  28. Synchronisation von Threads • barrier-Direktive:#pragma omp barrier • Thread setzt Ausführung erst fort, wenn alle Threads die barrier-Direktive erreicht haben • Bezieht sich nur auf Threads des eigenen „Teams“ • Direktive muss von allen oder von keinem Thread erreicht werden • Sonst: Verklemmung (Deadlock)

  29. Ausführung nur durch Master-Thread • Master-Direktive:#pragma omp master { Anweisungsblock } • Anweisungsblock wird ausschließlich von Master-Thread bearbeitet • Bei verschachtelter Parallelisierung:Master-Thread des innersten parallelen Bereichs • Alle anderen Threads ignorieren den Block

  30. Gliederung • Einführung • Vergleich von OpenMPI und MPI • Grundlagen • Parallelisierung von Programmbereichen • Koordination und Synchronisation von Threads • Zusammenfassung

  31. Zusammenfassung • Einheitlicher Standard für Programmierung von Parallelrechnern mit gemeinsamem Speicher • Ermöglicht leichte Parallelisierung bestehender Programme (inkrementelle Parallelisierung) • Parallelisierung mittels Compiler-Direktiven • Fork-join-Prinzip • Unterstützung namhafter Hersteller • http://www.openmp.org/

  32. Vielen Dankfür die Aufmerksamkeit

More Related