Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Shared Memory Programmierung: OpenMP

Ähnliche Präsentationen


Präsentation zum Thema: "Shared Memory Programmierung: OpenMP"—  Präsentation transkript:

1 Shared Memory Programmierung: OpenMP
Was ist OpenMP? Sprachmittel: Direktiven Laufzeitroutinen Umgebungsvariablen OpenMP auf IBMs RS/6000 SP Shared Memory Programmierung: OpenMP

2 Shared Memory Programmierung: OpenMP
OpenMP - Einführung OpenMP ist ein Quasi-Standard für SMP-Programmierung Definiert durch das OpenMP Architecture Review Board (ARB) Im ARB sind beteiligt: Hersteller von SMP-Hardware Hersteller von HPC-Anwendungen u. -Tools Forschungsinstitutionen OpenMP kann mit Fortran77, Fortran90, C und C++ eingesetzt werden Sprachmittel von OpenMP sind Direktiven Laufzeitroutinen Umgebungsvariablen Shared Memory Programmierung: OpenMP

3 Shared Memory Programmierung: OpenMP
OpenMP - Versionen OpenMP 1.0 für Fortran Okt. 1997 OpenMP 1.0 für C/C++ Okt. 1998 OpenMP 1.1 für Fortran Okt. 1999 OpenMP 2.0 für Fortran Nov. 2000 OpenMP 2.0 für C/C++ Nov. 2001 OpenMP ist auf allen gängigen SMP-Plattformen verfügbar, z. Zt. Version 1.0/1.1 Shared Memory Programmierung: OpenMP

4 OpenMP-Parallelverarbeitungsmodell
Fork-Join-Parallelisierung: Master-Thread erzeugt ein Team von Threads Master-Thread parallel regions Shared Memory Programmierung: OpenMP

5 Basis-Konstrukt: PARALLEL REGION
call work1(arg1) !$OMP PARALLEL call work2(arg2) !$OMP END PARALLEL call work3(arg3) Durch die Direktive PARALLEL wird ein Team von Threads erzeugt, Alle Threads führen gleichzeitig die zwischen PARALLEL und END PARALLEL stehenden Instruktionen aus. Der Master Thread wartet bei END PARALLEL bis alle Team-Threads mit der Arbeit in der parallelen Region fertig sind und bearbeitet dann allein die folgenden Instruktionen Shared Memory Programmierung: OpenMP

6 OpenMP Programmiermodell
Shared Memory SPMD Single Program Multiple Data: Alle Threads bearbeiten das gleiche Programm Jeder Thread bearbeitet unterschiedliche Daten, die durch Thread-ID gekennzeichnet werden Variablen sind Gemeinsam (shared) für alle Threads Vervielfacht (private) für jeden Thread Kommunikation zwischen Threads über gemeinsame Variablen Synchronisation über geschützte Veränderung gemeinsamer Variablen Shared Memory Programmierung: OpenMP

7 Informationen über OpenMP
Die Web-Seite der OpenMP-Organisation Standard-Definitionen, Tutorien, FAQs Information zu OpenMP-Implementierungen Hinweise zu weiterer Literatur R. Chandra, L. Dagum, D. Kohr, D. Maydan, J. McDonald, R. Menon: Parallel Programming in OpenMP Academic Press,San Diego, 2000, ISBN R. Eigenmann, M. J. Voss (Eds): OpenMP Shared Memory Programming Springer LNCS 2104, Berlin, 2001, ISBN X HLRS Parallel Programming Workshop Online Shared Memory Programmierung: OpenMP

8 Sprachmittel von OpenMP
Compiler - Direktiven zur Erzeugung von Threads zur Steuerung der Lastverteilung zur Charakterisierung der Variablen (shared, private, ...) zur Synchronisation von Threads Laufzeitfunktionen Steuerung der Anzahl von Threads Information über Thread-ID Verwaltung von locks Umgebungsvariablen Steuerung von Thread-Zahl, Lastverteilung,... Shared Memory Programmierung: OpenMP

9 Shared Memory Programmierung: OpenMP
Syntax der Direktiven Generisch sentinel directive_name [clause,...] Fortran90, fixed format sentinel : !$OMP, C$OMP, oder *$OMP *$OMP PARALLEL SHARED(a,b) !$OMP PARALLEL !$OMP& SHARED(a,b) Fortran90, free format sentinel : !$OMP !$OMP PARALLEL SHARED(a,b) !$OMP PARALLEL & !$OMP SHARED(a,b) Direktiven für Fortran nicht Case-sensitiv Shared Memory Programmierung: OpenMP

10 Shared Memory Programmierung: OpenMP
Syntax der Direktiven C / C++ sentinel : #pragma omp #pragma omp parallel Direktiven für C / C++ sind Case-sensitiv Shared Memory Programmierung: OpenMP

11 Portierbarkeit von OpenMP Programmen
Bei Compilierung für sequentielle Programmausführung werden Direktiven als Kommentare behandelt Laufzeitfunktionen sind in sequentieller Umgebung nicht bekannt, sie können durch bedingte Compilierung ausgeblendet werden: !$ write(6,*) OMP_GET_NUM_PROCS(),‘Prozessoren‘ Oder mit cpp preprocessor: #ifdef _OPENMP write(6,*) OMP_GET_NUM_PROCS(),‘Prozessoren‘ #else write(6,*) ‘ein Prozessor‘ #endif Shared Memory Programmierung: OpenMP

12 Reichweite von Direktiven
Direktiven beziehen sich meistens auf einen strukturierten Block (structured block) Strukturierter Block: Folge von Programmanweisungen mit einem einzigen Eintrittspunkt (am Anfang des Blocks) und einem einzigen Austrittspunkt (am Ende des Blocks). Erlaubt ist zusätzlich das STOP-Statement (Fortran) bzw. exit() -Statement (C/C++) Fortran !$OMP PARALLEL call work !$OMP END PARALLEL C #pragma omp parallel { work(); } Shared Memory Programmierung: OpenMP

13 Die PARALLEL Direktive
!$OMP PARALLEL [clause[[,] clause] ... ] Programm-block !$OMP END PARALLEL Clause : PRIVATE(list) SHARED(list) DEFAULT(PRIVATE | SHARED | NONE) FIRSTPRIVATE(list) REDUCTION((operator|intrinsic):list) IF(scalar_logical_expression) COPYIN(list) Shared Memory Programmierung: OpenMP

14 Die PARALLEL Direktive
Der Programm-Block zwischen PARALLEL und END PARALLEL wird redundant von nthr Threads ausgeführt. nthr kann im Programm durch eine Laufzeitfunktion gesetzt werden: call OMP_SET_NUM_THREADS(nthr) oder durch eine Umgebungsvariable (z.B. in der ksh): export OMP_NUM_THREADS=nthr Die Parallel Direktive impliziert eine Synchronisation: Der Master-Thread setzt die Programmausführung erst fort, wenn alle Threads im Team ihren Programm-Block beendet haben. Shared Memory Programmierung: OpenMP

15 Die PARALLEL Direktive
call OMP_SET_NUM_THREADS(4) !$OMP PARALLEL DEFAULT(SHARED) PRIVATE(tid) tid = OMP_GET_THREAD_NUM() call work(tid,a) !$OMP END PARALLEL call OMP_SET_NUM_THREADS(4) work(0,a) work(1,a) work(2,a) work(3,a) Synchronisationspunkt Shared Memory Programmierung: OpenMP

16 Direktiven zur Arbeitsverteilung
Arbeitverteilung innerhalb einer parallelen Region SECTIONS / END SECTIONS die in den verschiedenen Sections spezifizierten Programm-Blöcke werden auf die Threads verteilt SINGLE / END SINGLE der Programm-Block in der Single Region wird nur von einem Thread durchlaufen DO / END DO DO-Schleife wird auf die Threads verteilt Kombinierte Direktiven PARALLEL DO / END PARALLEL DO PARALLEL SECTIONS / END PARALLEL SECTIONS Shared Memory Programmierung: OpenMP

17 Shared Memory Programmierung: OpenMP
Die DO Direktive !$OMP DO [clause[[,] clause] ... ] do-Schleife [!$OMP END DO [NOWAIT]] clause : PRIVATE(list) FIRSTPRIVATE(list) LASTPRIVATE(list) REDUCTION(operator|intrinsic:list) SCHEDULE(type[,chunk]) ORDERED NOWAIT : Keine Synchronisation am Ende der do - Region !$OMP END DO kann weggelassen werden Shared Memory Programmierung: OpenMP

18 Lastverteilung in der DO Region
SCHEDULE(type[,chunk]) SCHEDULE(STATIC[,chunk]):Iterationen werden in Portionen der Größe chunk statisch auf die Threads verteilt. Ohne Angabe von chunk bekommt jeder Thread einen Teil der Iterationen mit aufeinander folgenden Indizes SCHEDULE(DYNAMIC[,chunk]):Iterationen werden in Portionen der Größe chunk dynamisch auf die Threads verteilt. Ohne Angabe von chunk ist chunk = 1 SCHEDULE(GUIDED[,chunk]):Iterationen werden in Portionen der Größe MAX( chunk, CEILING(#verbleibender Iterationen / #Threads)) dynamisch auf die Threads verteilt. Ohne Angabe von chunk ist chunk = 1 SCHEDULE(RUNTIME): Die Lastverteilung kann zur Laufzeit durch Setzen der Umgebungsvariablen OMP_SCHEDULE bestimmt werden. Der Default für die Lastverteilung ist STATIC. Shared Memory Programmierung: OpenMP

19 Shared Memory Programmierung: OpenMP
Die DO Direktive call OMP_SET_NUM_THREADS(4) !$OMP PARALLEL DEFAULT(SHARED) PRIVATE(tid) tid = OMP_GET_THREAD_NUM() !$OMP DO do i = 1 , a(i) = b(i) + c(i) end do !$OMP END DO NOWAIT call work(tid,a) !$OMP END PARALLEL OMP_SET_NUM_THREADS(4) a(1:25) a(26:50) a(51:75) a(76:100) work(0,a) work(1,a) work(2,a) work(3,a) Synchronisationspunkt Shared Memory Programmierung: OpenMP

20 Die SECTIONS Direktive
!$OMP SECTIONS [clause[[,] clause] ... ] [!$OMP SECTION] Programm-Block [!$OMP SECTION Programm-Block] . . . !$OMP END SECTIONS [NOWAIT] clause : PRIVATE(list) FIRSTPRIVATE(list) LASTPRIVATE(list) REDUCTION(operator|intrinsic:list) Shared Memory Programmierung: OpenMP

21 Die SECTIONS Direktive
call OMP_SET_NUM_THREADS(2) !$OMP PARALLEL DEFAULT(SHARED) PRIVATE(tid) tid = OMP_GET_THREAD_NUM() !$OMP SECTIONS !$OMP SECTION call work_s1(a) call work_s2(a) !$OMP END SECTIONS call work(tid,a) !$OMP END PARALLEL OMP_SET_NUM_THREADS(2) work_s1(a) work_s2(a) work(0,a) work(1,a) Synchronisationspunkte Shared Memory Programmierung: OpenMP

22 Shared Memory Programmierung: OpenMP
Die SINGLE Direktive !$OMP SINGLE [clause[[,] clause] ... ] Programm-Block !$OMP END SINGLE [NOWAIT] clause : PRIVATE(list) FIRSTPRIVATE(list) Programm-Block wird nur von einem einzigen Thread durchlaufen. Alle anderen Threads warten bei END SINGLE bis der aktive Thread fertig ist. Diese Synchronisation entfällt mit NOWAIT. Shared Memory Programmierung: OpenMP

23 Shared Memory Programmierung: OpenMP
Die SINGLE Direktive call OMP_SET_NUM_THREADS(2) !$OMP PARALLEL DEFAULT(SHARED) PRIVATE(tid) tid = OMP_GET_THREAD_NUM() !$OMP SINGLE call work_sgl(a) !$OMP END SINGLE call work(tid,a) !$OMP END PARALLEL OMP_SET_NUM_THREADS(2) work_sgl(a) work(0,a) work(1,a) Synchronisationspunkte Shared Memory Programmierung: OpenMP

24 Kombinierte Direktiven
!$OMP PARALLEL DO [clause[[,] clause] ... ] do-Schleife !$OMP END PARALLEL DO !$OMP PARALLEL SECTIONS [clause[[,] clause] ... ] !$OMP SECTION Programm-Block1 Programm-Block2 . . . !$OMP END PARALLEL SECTIONS Shared Memory Programmierung: OpenMP

25 Synchronisations-Direktiven
MASTER / END MASTER wird nur vom Master-Thread ausgeführt, alle anderen Threads setzen ohne Synchronisation die Programmausführung fort. CRITICAL / END CRITICAL wird nacheinander von jedem Thread einzeln ausgeführt BARRIER synchronisiert alle Threads ATOMIC kennzeichnet ununterbrechbare Operationen FLUSH garantiert Speicher-Konsistenz ORDERED / END ORDERED garantiert sequentielle Reihenfolge in Schleife Shared Memory Programmierung: OpenMP

26 Die CRITICAL Direktive
!$OMP CRITICAL [(name) ] Programm-Block !$OMP END CRITICAL [(name) ] Am Anfang einer kritischen Region wartet ein Thread, bis kein anderer Thread mehr im kritischen Blocks arbeitet (MUTEX). Mit name können kritische Regionen unterschieden werden Alle nichtbenannten kritischen Regionen verweisen auf einen gemeinsamen Namen. Shared Memory Programmierung: OpenMP

27 Shared Memory Programmierung: OpenMP
Die ATOMIC Direktive !$OMP ATOMIC statement ATOMIC gilt nur für die direkt folgende Anweisung. Die Direktive garantiert, dass die angewiesene Änderung eines Speicherinhaltes ununterbrochen ausgeführt wird. Mögliche Formen für statement sind: x = x op expr x = expr op x x = intr(x,expr) x = intr(expr,x) x = Skalare Variable expr = skalarer Ausdruck, der x nicht enthält op = +,*,-,/,.AND.,.OR.,.EQV.,NEQV intr = MAX, MIN, IAND, IOR, IEOR Shared Memory Programmierung: OpenMP

28 Shared Memory Programmierung: OpenMP
Die FLUSH Direktive !$OMP FLUSH [(list) ] Die FLUSH Direktive garantiert für alle Threads konsistente Werte u. a. für Variable mit dem Attribut SHARED (s. Standard). Alle Schreib- und Lese- Anweisungen für diese Variablen werden vollendet, bevor der Thread die FLUSH Direktive verläßt. List enthält die Variablen, auf die sich FLUSH bezieht, ohne list sind dies alle Variablen. Folgende Direktiven implizieren FLUSH: BARRIER,CRITICAL,END CRITICAL,END DO,END PARALLEL, END SECTIONS,END SINGLE,ORDERED,END ORDERED. Shared Memory Programmierung: OpenMP

29 Implizite Synchronisation
Folgende Direktiven implizieren eine Synchronisation mit BARRIER END PARALLEL END DO (außer mit NOWAIT) END SECTIONS (außer mit NOWAIT) END CRITICAL END SINGLE (außer mit NOWAIT) Folgende Direktiven implizieren eine Synchronisation mit FLUSH: BARRIER CRITICAL ORDERED END ORDERED Shared Memory Programmierung: OpenMP

30 Attribute und Direktiven für Daten
PRIVATE Private Variablen werden für jeden Thread vervielfältigt SHARED Shared Variablen werden von allen Threads benutzt DEFAULT definiert den Default für die Variablen-Attribute FIRSTPRIVATE private Variablen, die mit den Werten der Original-Variablen initialisiert werden LASTPRIVATE private Variablen, deren letzte Werte auf die Original-Variablen kopiert werden REDUCTION shared Variablen für Reduktionsoperationen in do-Schleifen !$OMP THREADPRIVATE / COPYIN Deklaration und Initialisierung von privaten COMMON-Blöcken Shared Memory Programmierung: OpenMP

31 Das Attribut REDUCTION
REDUCTION(operation:list) Die skalaren Variablen in list müssen das Attribut SHARED haben. Jeder Thread legt eine lokale Kopie der REDUCTION Variablen an und initialisiert sie. Am Ende der Schleife werden die lokalen Kopien in der REDUCTION Variablen zusammengeführt x = x op expr x = expr op x x = intr(x,expr) x = intr(expr,x) Einige intr können in expliziter Form erscheinen, z.B.: if (x.LT.expr) x = expr x = Skalare variable expr = skalarer Ausdruck, der x nicht enthält Shared Memory Programmierung: OpenMP

32 REDUCTION Operationen
operator | intrinsic Initialisierung + 0 * 1 _ 0 .AND. .TRUE. .OR. .FALSE. .EQV. .TRUE. .NEQV. .FALSE. MAX kleinste darstellbare Zahl MIN größte darstellbare Zahl IAND alle bits = 1 IOR alle bits = 0 IEOR alle bits = 0 Shared Memory Programmierung: OpenMP

33 Beispiel für REDUCTION
call OMP_SET_NUM_THREADS(4) sum = 0.0 !$OMP PARALLEL DEFAULT(SHARED) PRIVATE(tid) tid = OMP_GET_THREAD_NUM() !$OMP DO REDUCTION(+:sum) do i = 1 , sum = sum + a(i) end do !$OMP END DO call work(tid,a) !$OMP END PARALLEL OMP_SET_NUM_THREADS(4) a(1:25) a(26:50) a(51:75) a(76:100) work(0,a) work(1,a) work(2,a) work(3,a) Synchronisationspunkte Shared Memory Programmierung: OpenMP

34 THREADPRIVATE / COPYIN
!$OMP THREADPRIVATE(/cb/[, /cb/] ...) THREADPRIVATE macht benannte COMMON Blöcke innerhalb paralleler Regionen privat für alle Threads. Die Direktive muss nach der Deklarierung des COMMON Blöcke folgen. Außerhalb von parallelen Regionen und in MASTER Regionen sind diese COMMON Blöcke mit denjenigen des Master-Threads der parallelen Regionen assoziiert. COPYIN(list) Objekte in list (THREADPRIVATE deklarierte COMMON Blöcke oder Variablen aus solchen) werden beim Beginn der parallelen Region vom Master-Thread auf die privaten Kopien aller Threads kopiert Shared Memory Programmierung: OpenMP

35 Beispiel für THREADPRIVATE / COPYIN
COMMON /T/ A,B,C !$OMP THREADPRIVATE(/T/) ... CONTAINS SUBROUTINE BBB COMMON /T/ A !$OMP PARALLEL COPYIN(/T/) !$OMP END PARALLEL Shared Memory Programmierung: OpenMP

36 Laufzeit-Routinen in OpenMP
SUBROUTINE OMP_SET_NUM_THREADS(nthr) Bestimmt die Zahl der Threads in der nächsten parallelen Region FUNCTION OMP_GET_NUM_THREADS() Gibt die Anzahl aktiver Threads FUNCTION OMP_GET_MAX_THREADS() Gibt die Zahl von Threads, die maximal aktiviert werden können FUNCTION OMP_GET_THREAD_NUM() Gibt die Thread-ID FUNCTION OMP_GET_NUM_PROCS() Gibt die Anzahl verfügbarer Prozessoren Shared Memory Programmierung: OpenMP

37 Laufzeit-Routinen in OpenMP
LOGICAL FUNCTION OMP_IN_PARALLEL() .TRUE., wenn aus einer parallelen Region gerufen, sonst .FALSE. SUBROUTINE OMP_SET_DYNAMIC(.TRUE.) Anzahl der Threads kann dynamisch zur Laufzeit bestimmt werden FUNCTION OMP_GET_DYNAMIC() .TRUE., wenn SET_DYNAMIC aktiviert, sonst .FALSE. SUBROUTINE OMP_SET_NESTED(.TRUE.|.FALSE.) Geschachtelte parallele Regionen werden mit .FALSE. serialisiert, mit .TRUE. implementierungsabhängig serialisiert oder durch Erzeugung weiterer Threads parallelisiert LOGICAL FUNCTION OMP_GET_NESTED() .TRUE. in Regionen geschachtelter Parallelisierung, sonst.FALSE. Shared Memory Programmierung: OpenMP

38 LOCK Routinen in OpenMP
SUBROUTINE OMP_INIT_LOCK(var) Initialisiert ein LOCK mit der Lock-Variablen var SUBROUTINE OMP_DESTROY_LOCK(var) Gibt die Lock-Variable var frei SUBROUTINE OMP_SET_LOCK(var) Der rufende Thread wartet, bis der LOCK var frei ist und setzt ihn SUBROUTINE OMP_UNSET_LOCK(var) Der rufende Thread gibt den LOCK var frei LOGICAL FUNCTION OMP_TEST_LOCK(var) Setzt den LOCK, wenn er frei ist und gibt .TRUE., sonst .FALSE. Shared Memory Programmierung: OpenMP

39 Umgebungsvariablen in OpenMP
OMP_NUM_THREADS z.B. OMP_NUM_THREADS=4 Setzt die Anzahl von Threads fest, die in parallelen Regionen eingesetzt werden OMP_SCHEDULE z.B. OMP_SCHEDULE=“STATIC,5“ Legt die Lastverteilung in DO und PARALLEL DO Regionen fest, die mit dem Attribut SCHEDULE(RUNTIME) versehen sind OMP_DYNAMIC z.B. OMP_DYNAMIC=FALSE Erlaubt oder verbietet dynamische Thread-Erzeugung OMP_NESTED z.B. OMP_NESTED=TRUE Erlaubt oder verbietet geschachtelte Parallelisierung Shared Memory Programmierung: OpenMP

40 Shared Memory Programmierung: OpenMP
OpenMP auf IBM SP C für AIX 5.0 unterstützt OpenMP 1.0 für C/C++ Aufruf: xlc_r -qsmp=omp XL Fortran 7.1 unterstützt OpenMP 1.1 für Fortran Aufruf: xlf90_r -qsmp=omp xlf_r -qsmp=omp Shared Memory Programmierung: OpenMP

41 SMP Erweiterungen in XLF
!SMP$ PARALLEL DO SCHEDULE(AFFINITY,n) Aufeinanderfolgende Blöcke von n Iterationen werden bevorzugt vom gleichen Thread bearbeitet COMMON /cn/ !IBM* THREADLOCAL/cn/ Definiert Thread-spezifische COMMON Blöcke !SMP$ DO SERIAL Verhindert die Parallelisierung der folgenden do-Schleife Shared Memory Programmierung: OpenMP


Herunterladen ppt "Shared Memory Programmierung: OpenMP"

Ähnliche Präsentationen


Google-Anzeigen