Parallele Programmierung mit OpenMP



Ähnliche Dokumente
Parallele Programmierung mit OpenMP

Parallele Programmierung mit OpenMP

Zählen von Objekten einer bestimmten Klasse

OpenMP. Viktor Styrbul

Objektorientierte Programmierung

Master-Thread führt Programm aus, bis durch die Direktive

OpenMP am Beispiel der Matrizenmultiplikation

C++ Grundlagen. ++ bedeutet Erweiterung zum Ansi C Standard. Hier wird eine Funktion eingeleitet

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Lehrer: Einschreibemethoden

AutoCAD Dienstprogramm zur Lizenzübertragung

Systeme 1. Kapitel 6. Nebenläufigkeit und wechselseitiger Ausschluss

Einige Grundlagen zu OpenMP

Praktikum: Paralleles Programmieren für Geowissenschaftler

Klausur in Programmieren

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Allgemeines. Verschiedene Sprachkonzepte C-Sprachfamilie C-ähnliche Programmiersprachen Allgemeines zu C. #include <stdio.h>

OpenMP - Threading- Spracherweiterung für C/C++ Matthias Klein, Michael Pötz Systemprogrammierung 15. Juni 2009

Einführung in die Programmierung

Version 0.3. Installation von MinGW und Eclipse CDT

Programmierkurs Java

Informationen zur Verwendung von Visual Studio und cmake

Erfahrungen mit Hartz IV- Empfängern

1 Vom Problem zum Programm

Stundenerfassung Version 1.8 Anleitung Arbeiten mit Replikaten

C++ mit Eclipse & GCC unter Windows

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Threads und OpenMP. Frank Mietke Cluster- & Gridcomputing Frank Mietke 7/4/04

DLLs (dynamic loaded libraries) mit MingW erstellen

Einführung in die C-Programmierung

Installationsanleitung Sander und Doll Mobilaufmaß. Stand

Angewandte Mathematik und Programmierung

Tutorium Rechnerorganisation

Wie man Registrationen und Styles von Style/Registration Floppy Disketten auf die TYROS-Festplatte kopieren kann.

Automatisches Parallelisieren

Enigmail Konfiguration

Propädeutikum. Dipl.-Inf. Frank Güttler

Professionelle Seminare im Bereich MS-Office

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

1. Einführung in OpenMP

Installation und Inbetriebnahme von Microsoft Visual C Express

5 DATEN Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom b

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Programmierung in C. Grundlagen. Stefan Kallerhoff

Statuten in leichter Sprache

Software-Engineering und Optimierungsanwendungen in der Thermodynamik

affilinet_ Flash-Spezifikationen

Java 7. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Dezember 2011 JAV7

teamsync Kurzanleitung

Handbuch. NAFI Online-Spezial. Kunden- / Datenverwaltung. 1. Auflage. (Stand: )

5. Tutorium zu Programmieren

Installation der Eicon Diva PCI Karte unter Windows XP

Drucken aus der Anwendung

Beispiel: Schleifenparallelisierung

Programmieren in C. Rekursive Funktionen. Prof. Dr. Nikolaus Wulff

Speicher in der Cloud

Anbindung des eibport an das Internet

Node Locked Lizenzierung für Solid Edge V19 bis ST3

Silca Software ERKLÄRUNG. February 2013 Copyright Silca S.p.A. V.2.0

NODELOCKED LIZENZ generieren (ab ST4)

Programmieren. 10. Tutorium 4./ 5. Übungsblatt Referenzen

S7-Hantierungsbausteine für R355, R6000 und R2700

Adobe Photoshop CS2, CS3, CS4, CS5 mit Auto-SoftProof-Ansicht

Um die Rücklagen ordnungsgemäß zu verbuchen, ist es wichtig, Schritt-für-Schritt vorzugehen:

Die Java Stream API. Funktionale Programmierung mit der Stream API des JDK 1.8. Prof. Dr. Nikolaus Wulff

Kundenspezifische Preise im Shop WyRu Online-Shop

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3

Dokumentenverwaltung im Internet

Datenbank LAP - Chefexperten Detailhandel

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Deklarationen in C. Prof. Dr. Margarita Esponda

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016

Jederzeit Ordnung halten

Anleitung über den Umgang mit Schildern

Arbeiten mit UMLed und Delphi

1. Zugriff auf das Lonza Netzwerk von ihrem privaten PC oder von einem Internet Café

Pakete dienen dazu, die Software eines Projektes in größere inhaltlich zusammengehörige Bereiche mit eigenem Namen einzuteilen (siehe Java API).

KeePass Anleitung. 1.0Allgemeine Informationen zu Keepass. KeePass unter Windows7

Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert

Matrix42. Use Case - Sicherung und Rücksicherung persönlicher Einstellungen über Personal Backup. Version September

Advoware mit VPN Zugriff lokaler Server / PC auf externe Datenbank

Einführung in die Programmierung (EPR)

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Dokumentation IBIS Monitor

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Dann zahlt die Regierung einen Teil der Kosten oder alle Kosten für den Dolmetscher.

C/C++ Programmierung

PTV VISWALK TIPPS UND TRICKS PTV VISWALK TIPPS UND TRICKS: VERWENDUNG DICHTEBASIERTER TEILROUTEN

10.6 Programmier-Exits für Workitems

Punkt 1 bis 11: -Anmeldung bei Schlecker und 1-8 -Herunterladen der Software

Zwischenablage (Bilder, Texte,...)

Einführung in die Java- Programmierung

Stepperfocuser 2.0 mit Bootloader

Objektorientiertes Programmieren mit Suse Linux

Transkript:

Parallele Programmierung mit OpenMP Wolfgang Dautermann FH Joanneum Chemnitzer Linuxtage 2008

1 Motivation 2 OpenMP Übersicht 3 Hello World - der erste Code 4 OpenMP-Compilerdirektiven Threaderzeugung Lastverteilung auf mehrere Threads Gültigkeitsbereiche von Daten Synchronisation 5 OpenMP Funktionen 6 Umgebungsvariablen 7 Compiler, die OpenMP unterstützen

Parallelisieren wozu? Eine CPU immer schneller machen, gelingt heute nicht mehr, stattdessen werden Dual- und Quadcore CPUs in die Rechner (inzwischen auch in handelsübliche PCs) eingebaut. Normalerweise nutzt Software aber nur eine CPU - v.a. bei rechenintensiven Aufgaben eine Verschwendung. Software wird standardmässig Step-by-Step abgearbeitet muss daher parallelisiert werden.

Parallelisierungsmethoden Distributed Memory mehrere einzelne Rechner in einem Cluster. Message Passing Interface (MPI) Shared Memory mehrere CPUs in einem Rechner, die auf einen gemeinsamen Speicher zugreifen können. OpenMP Implizit automatisch durch den Compiler, keine speziellen Anweisungen, Funktionen, etc. notwendig. Explizit macht der Programmierer durch spezielle Anweisungen, Funktionen, etc.

OpenMP - Übersicht Explizite shared Memory Parallelisierung Erweiterung für existierende Programmiersprachen (C/C++/Fortran) Hauptsächlich über Compiler Direktiven Einige wenige Library-Funktionen Inkrementelle Parallelisierung (Parallelisierung eines existierenden seriellen Programms). Schwerpunkt: Parallelisierung von Loops.

OpenMP Fork-Join Ausführungsmodell Abbildung: Fork-join Modell von OpenMP

OpenMP Architecture Review Board (... von der OpenMP Homepage) The OpenMP Architecture Review Board or the OpenMP ARB or just the ARB, is the non-profit corporation that owns the OpenMP brand, oversees the OpenMP specification and produces and approves new versions of the specification. Etliche Firmen sind darin vertreten herstellerunabhängiger Standard zur Parallelprogrammierung Permanent Members of the ARB: AMD, Cray, Fujitsu, HP, IBM, Intel,Microsoft, NEC, The Portland Group, SGI, Sun Auxiliary Members of the ARB: ASC/LLNL, compunity, EPCC, NASA, RWTH Aachen

Ein Hello World Programm mit OpenMP (C) # ifdef _OPENMP # include <omp.h > # endif # include < stdio.h > int main ( void ) { int i; # pragma omp parallel for for ( i = 0; i < 4; ++ i) { int id = omp_ get_ thread_ num (); printf (" Hello World from thread % d\ n", id ); if ( id ==0) printf (" There are %d threads \n", omp_get_num_threads ()); } return 0; }

Ein Hello World Programm mit OpenMP (Fortran) PROGRAM HELLO USE omp_ lib INTEGER ID, NTHRDS, I C $OMP PARALLEL DO PRIVATE (ID,I, NTHRDS ) DO I =1,4 ID = OMP_ GET_ THREAD_ NUM () PRINT *, ' HELLO WORLD FROM THREAD ', ID IF ( ID. EQ. 0 ) THEN NTHRDS = OMP_ GET_ NUM_ THREADS () PRINT *, ' THERE ARE ', NTHRDS, ' THREADS ' END IF END DO C $OMP END PARALLEL DO END

Compilerdirektiven OpenMP wird hauptsächlich über Compilerdirektiven definiert. Direktivenformat in C/C++ # pragma omp direktivenname [ klauseln...] Direktivenformat in Fortran C234567! $OMP direktivenname [ klauseln...] [! Kommentar ] (in Fortran sind auch andere Sentinels erlaubt 1 (C$OMP, *$OMP). 1 nur in fixed source form

Compilerdirektiven II für nicht OpenMP-fähige Fortran Compiler erscheinen diese Direktiven als Kommentar. nicht OpenMP-fähige C-Compiler ignorieren unbekannte Direktiven: $ gcc - Wall test. c # ( alte gcc Version ( < 4. 2)) test.c: In function 'main ': test. c : 12: warning : ignoring # pragma omp parallel $ Werden OpenMP Compilerdirektiven in ein Programm eingefügt werden, kann das Programm weiterhin von jedem (auch nicht OpenMP-fähigen) Compiler compiliert werden.

Bedingte Compilierung C/C++: Das Makro _OPENMP wird definiert. # ifdef _ OPENMP /* Openmp spezifischer Code, z.b. */ nummer = omp_ get_ thread_ num () ; # endif Fortran: OpenMP erlaubt die bedingte Compilierung in Fortran. C234567! $ NUMMER = OMP_ GET_ THREAD_ NUM () Erscheint als Kommentar, wenn OpenMP nicht aktiviert ist (bzw. bei einem nicht OpenMP-fähigen Compiler), wird normal compiliert, wenn OpenMP aktiviert ist.

omp parallel Erzeugen zusätzlicher Threads, die Arbeit wird von allen Threads ausgeführt. Der originale Thread (master thread) bekommt die Thread ID 0. C/C++: # pragma omp parallel [ klauseln ] /* strukturierter Block ( keine gotos...) */ Fortran:! $OMP PARALLEL [ klauseln ] block! $OMP END PARALLEL

Arbeitsaufteilung zwischen den Threads I Loops: omp for (C/C++) Die Arbeit wird unter den Threads aufgeteilt (Beispiel: bei zwei Threads bearbeitet einer die Schleife von 1 ( N 2 1), der zweite von N 2 N)2 # pragma omp parallel [ klauseln...] # pragma omp for [ klauseln...] for (i =0;i<N;i ++) a[i ]= i*i; Dies kann auch zusammengefasst werden (omp parallel for): # pragma omp parallel for [ klauseln...] for (i =0;i<N;i ++) a[i ]= i*i; 2 Das Verhalten kann durch Verwendung der schedule()-klausel (static, dynamic, guided, runtime) beeinflusst werden...

Arbeitsaufteilung zwischen den Threads I Loops: omp do (Fortran) Die Arbeit von DO-Loops wird von allen Threads gemeinsam bearbeitet.! $OMP PARALLEL [ klauseln...]! $OMP DO [ klauseln...] DO I =1,N A(I) = I*I END DO! $OMP END DO! $OMP END PARALLEL Auch hier wieder möglich:! $OMP PARALLEL DO [ klauseln...] [...]! $OMP END PARALLEL DO!$OMP PARALLEL i=1 i=2 i=3 i=4!$omp DO i=5 i=6 i=7 i=8!$omp END DO i=9 i=10 i=11 i=12!$omp END PARALLEL (implizite) Barrier Abbildung: (par.) DO Schleife

Arbeitsaufteilung zwischen den Threads II Parallele Sections (C/C++) Die Arbeit wird unter den Threads aufgeteilt. Jeder bearbeitet eine Section. # pragma omp parallel [ klauseln...] # pragma omp sections [ klauseln...] { # pragma omp section [... Programmteil A läuft parallel zu B...] # pragma omp section [... Programmteil B läuft parallel zu A...] } Auch hier kann man das kombinieren: # pragma omp parallel sections [ klauseln...]

Arbeitsaufteilung zwischen den Threads II Parallele Sections (Fortran) Die Arbeit wird unter den Threads aufgeteilt. Jeder bearbeitet eine Section.! $OMP PARALLEL [ klauseln...]! $OMP SECTIONS [ klauseln...]! $OMP SECTION [... Programmteil A läuft parallel zu B...]! $OMP SECTION [... Programmteil B läuft parallel zu A...]! $OMP END SECTIONS! $OMP END PARALLEL Auch hier kann man das kombinieren:! $OMP PARALLEL SECTIONS [ klauseln...]

Arbeitsaufteilung zwischen den Threads III Parallel Workshare (nur Fortran) Für Operationen mit Arrays, z.b. REAL, DIMENSION (100,100) :: A, B, C [...]! $OMP PARALLEL WORKSHARE A = B + C! $OMP END PARALLEL WORKSHARE

Gültigkeitsbereiche von Daten - shared(), private(),... Achtung: Häufige Fehlerquelle! Klauseln, die bei OpenMP-Direktiven angegeben werden, regeln wie Variablen zwischen den Threads ausgetauscht werden... shared(): Die Daten werden unter allen parallelen Regionen geshared, d.h. sie sind in allen Threads les- und schreibbar. Wenn ein Thread eine Variable ändert, ist sie auch in allen anderen Threads modifiziert. Default: Alle Variablen sind shared() ausser Schleifenvariablen bei OMP DO/omp for. private(): Jeder Thread bekommt eine private Kopie der Variablen, diese wird nicht initialisiert. Default: Nur Schleifenvariablen sind privat. default(shared private none): legt den Defaultwert fest. none: Jede Variable muss shared() oder private() deklariert werden.

Gültigkeitsbereiche von Daten II firstprivate(): wie private(), aber alle Kopien werden mit dem Wert der Variablen vor der parallelen Schleife/Region initialisiert. lastprivate(): Die Variable wird nach der parallelen Schleife/Region mit dem Wert aus dem Thread initialisiert, der (sequentiell) am spätesten drangekommen wäre.

Gültigkeitsbereiche von Daten II reduction() Aufsummieren, etc. a = 0 ; b = 0 ; # pragma omp parallel for private (i) shared (x, y, n) \ reduction (+: a, b) for (i =0; i <n; i ++) { a = a + x[i] ; b = b + y[i] ; } Eine lokale Kopie jeder Variable in reduction() wird erzeugt und abhängig vom Operator initialisiert (z.b. 0 für + ). Wenn dann (z.b.) 3 Threads je ein Drittel der Schleife bearbeiten, werden am Ende die Teilsummen aller Threads noch aufsummiert.

Synchronisation Barrier Alle Threads warten, bis alle diesen Punkt erreicht haben # pragma omp barrier (C/C ++)!$OMP BARRIER ( Fortran ) z.b. bei zwei parallelisierten for-schleifen # pragma omp parallel { # pragma omp for nowait for (i =0; i < N; i ++) a[i] = b[i] + c[i ]; # pragma omp barrier # pragma omp for for (i =0; i < N; i ++) d[i] = a[i] + b[i ]; } Pause Pause

Synchronisation II Critical/Atomic alle Threads führen den Code aus, aber nur einer zu einem Zeitpunkt. # pragma omp critical [ name ] { code - block } # pragma omp atomic [ name ] statement! $OMP CRITICAL [ name ] code - block! $OMP END CRITICAL! $OMP ATOMIC [ name ] statement Abbildung: CRITICAL Region Alle Threads warten am Beginn der critical Region, bis kein anderer Thread eine critical Region mit demselben Namen ausführt. critical Regionen ohne Namen werden alle demselben (nicht spezifizierten) Namen zugeordnet.

Synchronisation III Critical Codebeispiel # ifdef _OPENMP # include <omp.h > # endif # include <stdio.h> int main () { double a [1000000]; int i; # pragma omp parallel for for (i=0; i <1000000; i++) a[i ]=i; double summe = 0; # pragma omp parallel for shared ( summe ) private (i) for ( i =0; i < 1000000; i ++) { } summe = summe + a[i ]; } printf (" summe =% lf \n", summe ); Summiert (ähnlich wie reduction()) die Elemente des Arrays auf. Was ist das Problem?

Synchronisation III Critical Codebeispiel (korrekt) # ifdef _OPENMP # include <omp.h > # endif # include <stdio.h> int main () { double a [1000000]; int i; # pragma omp parallel for for (i=0; i <1000000; i++) a[i ]=i; double summe = 0; # pragma omp parallel for shared ( summe ) private (i) for ( i =0; i < 1000000; i ++) { # pragma omp critical ( summierung ) summe = summe + a[i ]; } printf (" summe =% lf \n", summe ); } Bei der Summierung kann eine Race-Condition auftreten. Diese muss mit #pragma omp critical vermieden werden.

Synchronisation IV Nur ein Thread soll eine Region ausführen z.b. für I/O # pragma omp master { [ Code der nur einmal ( nur vom Master Thread ) ausgeführt wird ] } # pragma omp single { [ Code der nur einmal ( nicht unbedingt vom Master Thread ) ausgeführt wird ] }

Synchronisation V Flush, Ordered FLUSH: sorgt für eine konsistente Sicht auf den Speicher. # pragma omp flush ( variablen )! $OMP FLUSH ( variablen ) ORDERED: Legt fest, dass die Reihenfolge der Ausführung der Iterationen des betreffenden Blocks die gleiche wie bei serieller Programmausführung sein muss zulässig nur innerhalb einer for-schleife # pragma omp for ordered {... } ;

OpenMP-Funktionen OpenMP stellt div. Library Funktionen zur Verfügung. Settings mit diesen Funktionen haben Vorrang vor den entsprechenden Umgebungsvariablen. Empfehlung: Verwendung nur mit #ifdef _OPENMP bzw. bedingter Compilierung (Fortran), damit der Code auch ohne OpenMP lauffähig bleibt. C/C++: #include <omp.h> Fortran: USE omp_lib

OpenMP-Funktionen II Threading int omp_get_num_threads() int omp_get_thread_num() int omp_in_parallel() void omp_set_num_threads(int)... Locking void omp_init_lock(omp_lock_t*) void omp_destroy_lock(omp_lock_t*) void omp_set_lock(omp_lock_t*) void omp_unset_lock(omp_lock_t*) int omp_test_lock(omp_lock_t*)......

Umgebungsvariablen OMP_NUM_THREADS=integer Maximale Anzahl der OpenMP-Threads OMP_SCHEDULE=kind[,chunk_size] (static, dynamic, guided) betrifft das Aufteilen der Arbeit in Loops: static: jeder Thread bekommt statisch gleich viele Iterationen zugeteilt dynamic: jeder Thread holt sich neue Arbeit ab, sobald er arbeitslos ist guided: wie dynamic, nur werden die zugewiesenen Pakete laufend kleiner OMP_DYNAMIC=true false (kann die Anzahl der Threads dynamisch modifiziert werden?) OMP_NESTED=true false

Compiler - gcc ab Version 4.2... ist möglicherweise (noch) nicht bei der eigenen Distribution dabei, aber selbstcompilieren ist kein grosses Kunststück: Download der akutellen Release von ftp://ftp.gnu.org/gnu/gcc/ (oder einem Mirror, z.b. ftp://gd.tuwien.ac.at/gnu/gcc/releases/ Selbstcompilieren von gcc tar xvjf gcc -4.2.3. tar. bz2 cd gcc -4.2.3./ configure -- prefix =/ opt / gcc -4.2.3 \ -- enable - languages = fortran,c,c ++ make # das dauert, Zeit für eine Tasse Kaffee... make install # als root

gcc - Verwenden des selbstcompilierten GCC Verwendung des selbstcompilierten GCC $ / opt /gcc -4.2.3/ bin / gcc - Wall - fopenmp helloworld.c $ export LD_LIBRARY_PATH =/ opt /gcc -4.2.3/ lib64 $ export OMP_ NUM_ THREADS =4 $./ a. out Hello World from thread 3 Hello World from thread 0 Hello World from thread 1 Hello World from thread 2 There are 4 threads $

gcc - Verwenden des selbstcompilierten GCC (mit -rpath) Die Linker-option -rpath codiert den Suchpfad für Libraries in das Binary. Vorteil: läuft (am eigenen System) ohne $LD_LIBRARY_PATH Hacks... Nachteil: läuft (möglicherweise) nur am eigenen System... Verwendung des selbstcompilierten GCC $ / opt /gcc -4.2.3/ bin / gcc - Wall - fopenmp \ -Wl,- rpath =/ opt /gcc -4.2.3/ lib64 helloworld.c $ export OMP_ NUM_ THREADS =4 $./ a. out Hello World from thread 3 Hello World from thread 0 There are 4 threads Hello World from thread 1 Hello World from thread 2 $

Compiler - Sun Studio 12 Download von http://developers.sun.com/sunstudio/ (Registrierung nötig) Verwendung des Sun CC $ cd / opt $ tar xvjf SunStudio12ml - linux - x86-200709 - ii. tar. bz2 $ cd $HOME $ / opt / sunstudio12 / bin / cc - xopenmp helloworld.c $ export OMP_NUM_THREADS =4 $./ a. out Hello World from thread 0 There are 4 threads Hello World from thread 2 Hello World from thread 3 Hello World from thread 1 $

Compiler - Intel Compiler Linux-Version für nichtkommerziellen Gebrauch ist gratis. Download von http://www.intel.com/cd/software/products/asmo-na/eng/ download/download/ (Registrierung nötig) Verwendung des Intel CC $ icc - openmp helloworld. c helloworld.c (8): ( col. 1) remark : OpenMP DEFINED LOOP WAS PARALLELIZED. $ export OMP_NUM_THREADS =4 $./ a. out Hello World from thread 0 There are 4 threads Hello World from thread 1 Hello World from thread 3 Hello World from thread 2 $

Links OpenMP Homepage: http://www.openmp.org OpenMP auf Wikipedia: http://en.wikipedia.org/wiki/openmp OpenMP Spezifikationen: http://www.compunity.org/speci/

Fragen? Ausblicke - was ich nicht behandelt habe... weitere OpenMP Direktiven und Funktionen (es gibt noch mehr,... ) 3 Vergleich mit anderen Modellen zur Parallelprogrammierung, z.b. MPI Vielen Dank für Ihre Aufmerksamkeit Wolfgang Dautermann wolfgang.dautermann@fh-joanneum.at 3 das war auch eine OpenMP-Einführung, kein Expertenvortrag