openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open...

22
openmp #openmp

Transcript of openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open...

Page 1: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

openmp

#openmp

Page 2: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Inhaltsverzeichnis

Über 1

Kapitel 1: Erste Schritte mit openmp 2

Bemerkungen 2

Versionen 2

Examples 2

Zusammenstellung 2

Parallele Hallo Welt mit OpenMP 3

Work Sharing-Konstrukt - Beispiel für eine For-Schleife 3

Reduktionsbeispiel 4

Kapitel 2: Bedingte parallele Ausführung 5

Examples 5

Bedingte Klauseln in parallelen OpenMP-Regionen 5

Kapitel 3: Einfaches Parallelbeispiel 6

Syntax 6

Bemerkungen 6

Examples 6

Parallele Hallo Welt mit OpenMP 6

Kapitel 4: OpenMP-Reduzierungen 8

Bemerkungen 8

Examples 8

Annäherung an PI Hand-Crafting der #pragma omp-Reduktion 8

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma atomic 8

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma omp kritisch 9

Annäherung von PI mit #pragma omp Reduktionsklausel 9

Kapitel 5: OpenMP-Reduzierungen 10

Examples 10

Annäherung von PI mit #pragma omp Reduktionsklausel 10

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma omp kritisch 10

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma atomic 10

Annäherung an PI Hand-Crafting der #pragma omp-Reduktion 11

Page 3: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Kapitel 6: Schleifenparallelität in OpenMP 12

Parameter 12

Bemerkungen 12

Examples 13

Typisches Beispiel in C 13

Dasselbe Beispiel in Fortran 14

Beispiele kompilieren und ausführen 14

Addition zweier Vektoren mit OpenMP parallel zum Konstrukt 15

Kapitel 7: Unregelmäßiger OpenMP-Parallelismus 16

Bemerkungen 16

Examples 16

Parallele Verarbeitung eines C ++ - Listencontainers mit OpenMP-Tasks 16

Rekursive Berechnung für Pi mit OpenMP-Aufgaben 17

Credits 19

Page 4: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Über

You can share this PDF with anyone you feel could benefit from it, downloaded the latest version from: openmp

It is an unofficial and free openmp ebook created for educational purposes. All the content is extracted from Stack Overflow Documentation, which is written by many hardworking individuals at Stack Overflow. It is neither affiliated with Stack Overflow nor official openmp.

The content is released under Creative Commons BY-SA, and the list of contributors to each chapter are provided in the credits section at the end of this book. Images may be copyright of their respective owners unless otherwise specified. All trademarks and registered trademarks are the property of their respective company owners.

Use the content presented in this book at your own risk; it is not guaranteed to be correct nor accurate, please send your feedback and corrections to [email protected]

https://riptutorial.com/de/home 1

Page 5: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Kapitel 1: Erste Schritte mit openmp

Bemerkungen

OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert und Anwendungsentwicklern die Möglichkeit gibt, inkrementell Parallelität zu ihren Anwendungscodes hinzuzufügen.

Die OpenMP-API-Spezifikation für die parallele Programmierung bietet eine Anwendungsprogrammierschnittstelle (Application Programming Interface, API), die die Multiprocessing-Programmierung für mehrere Plattformen mit gemeinsamem Speicher in C, C ++ und Fortran auf den meisten Plattformen unterstützt. Es besteht aus einer Reihe von Compiler-Direktiven, Bibliotheksroutinen und Umgebungsvariablen, die das Laufzeitverhalten beeinflussen.

Da sich OpenMP auf die Parallelität innerhalb eines Knotens konzentriert (Shared Memory Multiprocessing), kann es mit Message-Passing-Programmiermodellen wie MPI kombiniert werden, um es auf mehreren Knoten auszuführen.

Versionen

Ausführung Sprache Veröffentlichungsdatum

4,5 C / C ++ / Fortran 2015-11-01

4,0 C / C ++ / Fortran 2013-07-01

3.1 C / C ++ / Fortran 2011-07-01

3,0 C / C ++ / Fortran 2008-05-01

2,5 C / C ++ / Fortran 2005-05-01

2.0c C / C ++ 2002-03-01

2.0f Fortran 2000-11-01

1,0c C / C ++ 1998-10-01

1,0f Fortran 1997-10-01

Examples

Zusammenstellung

Es gibt viele Compiler, die verschiedene Versionen der OpenMP-Spezifikation unterstützen.

https://riptutorial.com/de/home 2

Page 6: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

OpenMP führt eine Liste hier mit dem Compiler , dass es und der unterstützten Version unterstützen. Um eine Anwendung mit OpenMP-Unterstützung zu kompilieren (und zu verknüpfen), müssen Sie im Allgemeinen nur ein Kompilierungsflag hinzufügen. Wenn Sie die OpenMP-API verwenden, müssen Sie den OpenMP-Header (omp.h) einfügen. Während die Header-Datei einen festen Namen hat, hängt das Compile-Flag vom Compiler ab. Das Folgende ist eine nicht erschöpfende Liste von Compilern und das Flag, das OpenMP aktiviert.

GCC (einschließlich gcc, g ++ und gfortran): -fopenmp•LLVM: -fopenmp•Intel Compiler-Suite (einschließlich icc, icpc und ifort): -qopenmp (und -fopenmp für Kompatibilität mit GCC / LLVM)

IBM XL Compiler-Suite (einschließlich xlc, xlC und xlf): -xlsmp=omp•PGI-Compiler-Suite (einschließlich pgcc pgc ++ pgfortran): '-mp'•

Parallele Hallo Welt mit OpenMP

#include <omp.h> #include <stdio.h> int main (int argc, char *argv[]) { #pragma omp parallel { printf ("Hello world! I'm thread %d out of %d threads.\n", omp_get_thread_num(), omp_get_num_threads()); } return 0; }

Dieser Code erstellt einfach ein Team von Threads (entsprechend der Umgebungsvariablen OMP_NUM_THREADS - und wenn nicht definiert, wird pro logischem Kern auf dem System ein OMP_NUM_THREADS erstellt), und jeder Thread identifiziert sich neben dem Drucken der typischen Hello-World-Nachricht.

Work Sharing-Konstrukt - Beispiel für eine For-Schleife

double res[MAX]; int i; #pragma omp parallel { #pragma omp for for (i=0;i< MAX; i++) { res[i] = huge(); } }

Die for-Schleife wird parallel ausgeführt. riesige () ist eine Methode, deren Ausführung zu lange dauern kann. OpenMP unterstützt eine Verknüpfung zum Schreiben des obigen Codes als:

double res[MAX]; int i; #pragma omp parallel for for (i=0;i< MAX; i++) {

https://riptutorial.com/de/home 3

Page 7: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

res[i] = huge(); }

Wir können auch eine Zeitplanklausel haben, die bewirkt, wie Schleifeniterationen Threads zugeordnet werden. Zum Beispiel:

#pragma omp parallel #pragma omp for schedule(static) for(i=0;I<N;i++) { a[i] = a[i] + b[i]; }

Unterschiedliche Planungsstile sind:

Zeitplan (statisch [, Stück]) Verteilen Sie Blöcke mit Iterationen der Größe "Chunk" an jeden Thread. Wenn nicht angegeben: Weisen Sie den verfügbaren Threads möglichst gleichmäßig zu

Zeitplan (dynamisch [, Stück]) Jeder Thread holt sich "Chunk" -Iterationen aus einer Warteschlange, bis alle Iterationen verarbeitet wurden.

Zeitplan (geführt [, Stück]) Threads greifen dynamisch Blöcke von Iterationen auf. Die Größe des Blocks beginnt groß und verkleinert sich mit der Berechnung auf einen "Block".

Zeitplan (Laufzeit) Zeitplan und Blockgröße werden aus der Umgebungsvariablen OMP_SCHEDULE übernommen.

Reduktionsbeispiel

#include <omp.h> void main () { int i; double ZZ, func(), res=0.0; #pragma omp parallel for reduction(+:res) private(ZZ) for (i=0; i< 1000; i++){ ZZ = func(I); res = res + ZZ; } }

In der letzten Zeile: Wird tatsächlich zu einer privaten Kopie hinzugefügt und dann nach der Schleife kombiniert. Der Compiler kümmert sich um die Details.

Erste Schritte mit openmp online lesen: https://riptutorial.com/de/openmp/topic/4354/erste-schritte-mit-openmp

https://riptutorial.com/de/home 4

Page 8: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Kapitel 2: Bedingte parallele Ausführung

Examples

Bedingte Klauseln in parallelen OpenMP-Regionen

#include <omp.h> #include <stdio.h> int main (void) { int t = (0 == 0); // true value int f = (1 == 0); // false value #pragma omp parallel if (f) { printf ("FALSE: I am thread %d\n", omp_get_thread_num()); } #pragma omp parallel if (t) { printf ("TRUE : I am thread %d\n", omp_get_thread_num()); } return 0; }

Ihre Ausgabe ist:

$ OMP_NUM_THREADS=4 ./test FALSE: I am thread 0 TRUE : I am thread 0 TRUE : I am thread 1 TRUE : I am thread 3 TRUE : I am thread 2

Bedingte parallele Ausführung online lesen: https://riptutorial.com/de/openmp/topic/6928/bedingte-parallele-ausfuhrung

https://riptutorial.com/de/home 5

Page 9: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Kapitel 3: Einfaches Parallelbeispiel

Syntax

#pragma omp parallel gibt an, dass der folgende Block von allen Threads ausgeführt werden soll.

int omp_get_num_threads (void) : gibt die Anzahl der Threads zurück, die in der parallelen Region arbeiten (auch bekannt als Team von Threads).

int omp_get_thread_num (void) : gibt den Bezeichner des aufrufenden Threads zurück (reicht von 0 bis N-1, wobei N an omp_get_num_threads() gebunden ist).

Bemerkungen

Sie können die Umgebungsvariable OMP_NUM_THREADS oder die Direktive num_threads in der #pragma parallel , um die Anzahl der ausgeführten Threads für die gesamte Anwendung bzw. für den angegebenen Bereich anzugeben.

Examples

Parallele Hallo Welt mit OpenMP

Der folgende C-Code verwendet das parallele OpenMP-Programmiermodell, um die Thread-ID und die Anzahl der Threads mithilfe mehrerer Threads in stdout zu schreiben.

#include <omp.h> #include <stdio.h> int main () { #pragma omp parallel { // ID of the thread in the current team int thread_id = omp_get_thread_num(); // Number of threads in the current team int nthreads = omp_get_num_threads(); printf("I'm thread %d out of %d threads.\n", thread_id, nthreads); } return 0; }

In Fortran 90+ sieht das entsprechende Programm folgendermaßen aus:

program Hello use omp_lib, only: omp_get_thread_num, omp_get_num_threads implicit none

https://riptutorial.com/de/home 6

Page 10: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

integer :: thread_id integer :: nthreads !$omp parallel private( thread_id, nthreads ) ! ID of the thread in the current team thread_id = omp_get_thread_num() ! Number of threads in the current team nthreads = omp_get_num_threads() print *, "I'm thread", thread_id, "out of", nthreads, "threads." !$omp end parallel end program Hello

Einfaches Parallelbeispiel online lesen: https://riptutorial.com/de/openmp/topic/4959/einfaches-parallelbeispiel

https://riptutorial.com/de/home 7

Page 11: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Kapitel 4: OpenMP-Reduzierungen

Bemerkungen

Alle 4 Versionen sind gültig, aber sie veranschaulichen verschiedene Aspekte einer Reduktion.

Standardmäßig muss das erste Konstrukt mit der reduction bevorzugt werden . Dies ist nur möglich, wenn einige Probleme explizit identifiziert werden, sodass möglicherweise eine der drei Alternativen untersucht wird.

Examples

Annäherung an PI Hand-Crafting der #pragma omp-Reduktion

int i; int n = 1000000; double area = 0; double h = 1.0 / n; #pragma omp parallel shared(n, h) { double thread_area = 0; // Private / local variable #pragma omp for for (i = 1; i <= n; i++) { double x = h * (i - 0.5); thread_area += (4.0 / (1.0 + x*x)); } #pragma omp atomic // Applies the reduction manually area += thread_area; // All threads aggregate into area } double pi = h * area;

Die Threads werden in der #pragma omp-Parallele erzeugt. Jeder Thread verfügt über einen unabhängigen / privaten Thread-Bereich, in dem die teilweise Addition gespeichert wird. Die folgende Schleife wird mit #pragma omp for unter den Threads verteilt. In dieser Schleife berechnet jeder Thread seinen eigenen Thread-Bereich, und nach dieser Schleife aggregiert der Code den Bereich nacheinander atomar durch

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma atomic

double area; double h = 1.0 / n; #pragma omp parallel for shared(n, h, area) for (i = 1; i <= n; i++) { double x = h * (i - 0.5);

https://riptutorial.com/de/home 8

Page 12: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

#pragma atomic area += (4.0 / (1.0 + x*x)); } pi = h * area;

In diesem Beispiel führen alle Threads eine Teilmenge des Iterationszählers aus und sammeln sich atomar im Bereich der gemeinsam genutzten Variablen an, wodurch sichergestellt wird, dass keine Aktualisierungen verloren gehen. Wir können hier das #pragma-Atom verwenden, da die gegebene Operation (+ =) atomar ausgeführt werden kann, was die Lesbarkeit im Vergleich zur Verwendung des #pragma omp-kritisch vereinfacht.

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma omp kritisch

double area; double h = 1.0 / n; #pragma omp parallel for shared(n, h, area) for (i = 1; i <= n; i++) { double x = h * (i - 0.5); #pragma omp critical { area += (4.0 / (1.0 + x*x)); } } double pi = h * area;

In diesem Beispiel führen alle Threads eine Teilmenge des Iterationszählers aus und sammeln sich atomar im Bereich der gemeinsam genutzten Variablen an, wodurch sichergestellt wird, dass keine Aktualisierungen verloren gehen.

Annäherung von PI mit #pragma omp Reduktionsklausel

int i; int n = 1000000; double area = 0; double h = 1.0 / n; #pragma omp parallel for shared(n, h) reduction(+:area) for (i = 1; i <= n; i++) { double x = h * (i - 0.5); area += (4.0 / (1.0 + x*x)); } pi = h * area;

In diesem Beispiel führen alle Threads eine Teilmenge des Iterationszählers aus. Jeder Thread hat seine lokale private Kopie des Bereichs und am Ende des parallelen Bereichs wenden sie alle die Additionsoperation (+) an, um den endgültigen Wert für den Bereich zu erzeugen.

OpenMP-Reduzierungen online lesen: https://riptutorial.com/de/openmp/topic/5653/openmp-reduzierungen

https://riptutorial.com/de/home 9

Page 13: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Kapitel 5: OpenMP-Reduzierungen

Examples

Annäherung von PI mit #pragma omp Reduktionsklausel

h = 1.0 / n; #pragma omp parallel for private(x) shared(n, h) reduction(+:area) for (i = 1; i <= n; i++) { x = h * (i - 0.5); area += (4.0 / (1.0 + x*x)); } pi = h * area;

In diesem Beispiel führen alle Threads eine Teilmenge des Iterationszählers aus. Jeder Thread hat seine lokale private Kopie des area und am Ende des parallelen Bereichs wenden sie alle die Additionsoperation ( + ) an, um den endgültigen Wert für den area zu erzeugen.

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma omp kritisch

h = 1.0 / n; #pragma omp parallel for private(x) shared(n, h, area) for (i = 1; i <= n; i++) { x = h * (i - 0.5); #pragma omp critical { area += (4.0 / (1.0 + x*x)); } } pi = h * area;

In diesem Beispiel führen alle Threads eine Teilmenge des Iterationszählers aus und sammeln sich atomar im area der gemeinsam genutzten Variablen area , wodurch sichergestellt wird, dass keine Updates verloren gehen.

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma atomic

h = 1.0 / n; #pragma omp parallel for private(x) shared(n, h, area) for (i = 1; i <= n; i++) { x = h * (i - 0.5); #pragma atomic area += (4.0 / (1.0 + x*x)); } pi = h * area;

https://riptutorial.com/de/home 10

Page 14: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

In diesem Beispiel führen alle Threads eine Teilmenge des Iterationszählers aus und sammeln sich atomar im area der gemeinsam genutzten Variablen area , wodurch sichergestellt wird, dass keine Updates verloren gehen. Wir können hier das #pragma atomic , da die gegebene Operation ( += ) atomar ausgeführt werden kann, was die Lesbarkeit im Vergleich zur Verwendung des #pragma omp critical .

Annäherung an PI Hand-Crafting der #pragma omp-Reduktion

h = 1.0 / n; #pragma omp parallel private(x) shared(n, h) { double thread_area = 0; // Private / local variable #pragma omp for for (i = 1; i <= n; i++) { x = h * (i - 0.5); thread_area += (4.0 / (1.0 + x*x)); } #pragma omp atomic // Applies the reduction manually area += thread_area; // All threads aggregate into area } pi = h * area;

Die Threads werden in der #pragma omp parallel . Jeder Thread verfügt über einen unabhängigen / privaten thread_area , in dem die teilweise Addition thread_area . Die folgende Schleife wird mit #pragma omp for unter den Threads #pragma omp for . In dieser Schleife berechnet jeder Thread seinen eigenen thread_area und nach dieser Schleife aggregiert der Code die Fläche nacheinander atomar durch #pragma omp atomic .

OpenMP-Reduzierungen online lesen: https://riptutorial.com/de/openmp/topic/5967/openmp-reduzierungen

https://riptutorial.com/de/home 11

Page 15: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Kapitel 6: Schleifenparallelität in OpenMP

Parameter

Klausel Parameter

private Kommagetrennte Liste der privaten Variablen

firstprivateWie private , aber vor dem Eintritt in die Schleife auf den Wert der Variablen initialisiert

lastprivateWie private , aber die Variable erhält den Wert, der der letzten Iteration der Schleife beim Beenden entspricht

reductionReduktionsoperator : Kommas getrennte Liste der entsprechenden Reduktionsvariablen

schedulestatic , dynamic , guided , auto oder runtime mit einer optionalen Chunk-Größe nach dem Koma für den 3-Former

collapseAnzahl perfekt geschachtelter Schleifen zum Zusammenfallen und Parallelisieren

orderedSagt, dass einige Teile der Schleife in der richtigen Reihenfolge gehalten werden müssen (diese Teile werden durch einige ordered Klauseln innerhalb des Schleifenkörpers spezifisch gekennzeichnet)

nowaitEntfernen Sie die implizite Barriere, die standardmäßig am Ende des Schleifenkonstrukts vorhanden ist

Bemerkungen

Die Bedeutung der schedule Klausel lautet wie folgt:

static[,chunk] : Verteilen Sie statisch (dh die Verteilung erfolgt vor dem Eintritt in die Schleife) die Iterationen der Schleife in Batch- chunk Größe in einem Round-Robin-Verfahren. Wenn chunk nicht angegeben wird, sind die Chunks so gleichmäßig wie möglich und jeder Thread erhält höchstens einen von ihnen.

dynamic[,chunk] : Verteilen Sie die Loop-Iterationen unter den Threads nach Chargen der chunk mit einer First-Come-First-Served-Policy, bis keine Charge übrig bleibt. Wenn nicht angegeben, wird chunk auf 1 gesetzt

guided[,chunk] : Wie dynamic aber mit Chargen, deren Größen immer kleiner werden (bis 1)•auto : Lass den Compiler und / oder die Laufzeitbibliothek entscheiden, was am besten geeignet ist

runtime : Verschieben Sie die Entscheidung zur Laufzeit anhand der Umgebungsvariablen •

https://riptutorial.com/de/home 12

Page 16: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

OMP_SCHEDULE . Wenn zur Laufzeit die Umgebungsvariable nicht definiert ist, wird die Standardplanung verwendet

Der Standard für den schedule ist die Implementierungsdefinition . In vielen Umgebungen ist es static , kann aber auch dynamic oder sehr wohl auto . Achten Sie daher darauf, dass Ihre Implementierung nicht implizit auf sie angewiesen ist, ohne sie explizit festzulegen.

In den obigen Beispielen haben wir die verschmolzene Form parallel for oder parallel do . Das Schleifenkonstrukt kann jedoch verwendet werden, ohne es mit der parallel Direktive in Form einer #pragma omp for [...] oder !$omp do [...] Standalone-Direktive innerhalb einer parallel Region zu !$omp do [...] .

Nur für die Fortran-Version ist (sind) die Schleifenindexvariable (n) der parallelisierten Schleifen standardmäßig immer private . Sie müssen daher nicht explizit als private deklariert werden (dies ist jedoch kein Fehler). Für die C- und C ++ - Version sind die Schleifenindizes wie alle anderen Variablen. Wenn sich ihr Gültigkeitsbereich außerhalb der parallelisierten Schleife (s) erstreckt (dh, wenn sie nicht wie for ( int i = ...) sondern eher als int i; ... for ( i = ... ) deklariert sind int i; ... for ( i = ... ) dann sind sie dies müssen als private deklariert werden.

Examples

Typisches Beispiel in C

#include <stdio.h> #include <math.h> #include <omp.h> #define N 1000000 int main() { double sum = 0; double tbegin = omp_get_wtime(); #pragma omp parallel for reduction( +: sum ) for ( int i = 0; i < N; i++ ) { sum += cos( i ); } double wtime = omp_get_wtime() - tbegin; printf( "Computing %d cosines and summing them with %d threads took %fs\n", N, omp_get_max_threads(), wtime ); return sum; }

In diesem Beispiel berechnen wir nur 1 Million Cosinus und summieren ihre Werte parallel. Wir prüfen die Ausführung auch, um zu sehen, ob die Parallelisierung Auswirkungen auf die Leistung hat. Da wir die Zeit messen, müssen wir schließlich sicherstellen, dass der Compiler die von uns geleistete Arbeit nicht optimiert. Wir geben also vor, das Ergebnis zu verwenden, indem wir es zurückgeben.

https://riptutorial.com/de/home 13

Page 17: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Dasselbe Beispiel in Fortran

program typical_loop use omp_lib implicit none integer, parameter :: N = 1000000, kd = kind( 1.d0 ) real( kind = kd ) :: sum, tbegin, wtime integer :: i sum = 0 tbegin = omp_get_wtime() !$omp parallel do reduction( +: sum ) do i = 1, N sum = sum + cos( 1.d0 * i ) end do !$omp end parallel do wtime = omp_get_wtime() - tbegin print "( 'Computing ', i7, ' cosines and summing them with ', i2, & & ' threads took ', f6.4,'s' )", N, omp_get_max_threads(), wtime if ( sum > N ) then print *, "we only pretend using sum" end if end program typical_loop

Hier berechnen und berechnen wir erneut 1 Million Cosinus. Wir setzen die Schleife zeitlich fest, und um unerwünschte Compiler-Optimierungen zu vermeiden, geben wir vor, das Ergebnis zu verwenden.

Beispiele kompilieren und ausführen

Auf einem 8-Cores-Linux-Computer mit GCC-Version 4.4 können die C-Codes folgendermaßen kompiliert und ausgeführt werden:

$ gcc -std=c99 -O3 -fopenmp loop.c -o loopc -lm $ OMP_NUM_THREADS=1 ./loopc Computing 1000000 cosines and summing them with 1 threads took 0.095832s $ OMP_NUM_THREADS=2 ./loopc Computing 1000000 cosines and summing them with 2 threads took 0.047637s $ OMP_NUM_THREADS=4 ./loopc Computing 1000000 cosines and summing them with 4 threads took 0.024498s $ OMP_NUM_THREADS=8 ./loopc Computing 1000000 cosines and summing them with 8 threads took 0.011785s

Für die Fortran-Version gibt es:

$ gfortran -O3 -fopenmp loop.f90 -o loopf $ OMP_NUM_THREADS=1 ./loopf Computing 1000000 cosines and summing them with 1 threads took 0.0915s $ OMP_NUM_THREADS=2 ./loopf Computing 1000000 cosines and summing them with 2 threads took 0.0472s $ OMP_NUM_THREADS=4 ./loopf Computing 1000000 cosines and summing them with 4 threads took 0.0236s

https://riptutorial.com/de/home 14

Page 18: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

$ OMP_NUM_THREADS=8 ./loopf Computing 1000000 cosines and summing them with 8 threads took 0.0118s

Addition zweier Vektoren mit OpenMP parallel zum Konstrukt

void parallelAddition (unsigned N, const double *A, const double *B, double *C) { unsigned i; #pragma omp parallel for shared (A,B,C,N) private(i) schedule(static) for (i = 0; i < N; ++i) { C[i] = A[i] + B[i]; } }

In diesem Beispiel werden zwei Vektoren ( A und B in C ) eingefügt, indem ein Team von Threads (z. B. durch die OMP_NUM_THREADS OMP_NUM_THREADS angegeben OMP_NUM_THREADS aufgerufen wird und jedem Thread ein Arbeitsblock zugewiesen wird (in diesem Beispiel statisch durch den schedule(static) zugewiesen Ausdruck).

Siehe Abschnitt "Anmerkungen" bezüglich der private(i) Wahlmöglichkeit.

Schleifenparallelität in OpenMP online lesen: https://riptutorial.com/de/openmp/topic/5657/schleifenparallelitat-in-openmp

https://riptutorial.com/de/home 15

Page 19: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Kapitel 7: Unregelmäßiger OpenMP-Parallelismus

Bemerkungen

Eine häufige Gefahr besteht darin zu glauben, dass alle Threads einer parallelen Region Tasks instanziieren (erstellen) sollen. Dies ist jedoch normalerweise nicht der Fall, wenn Sie so viele Tasks wie die Anzahl der Threads und der Anzahl der zu verarbeitenden Elemente erstellen möchten. Daher finden Sie in OpenMP-Taskcodes etwas Ähnliches

#pragma omp parallel #pragma omp single ... #pragma omp task { code for a given task; } ...

Examples

Parallele Verarbeitung eines C ++ - Listencontainers mit OpenMP-Tasks

#include <omp.h> #include <unistd.h> #include <iostream> #include <list> static void processElement (unsigned n) { // Tell who am I. The #pragma omp critical ensures that // only one thread sends data to std::cout #pragma omp critical std::cout << "Thread " << omp_get_thread_num() << " processing element " << n << std::endl; // Simulate some work usleep (n*1000); } int main (void) { std::list<unsigned> lst; // Fill the list for (unsigned u = 0; u < 16; ++u) lst.push_back (1+u); // Now process each element of the list in parallel #pragma omp parallel // Create a parallel region #pragma omp single // Only one thread will instantiate tasks

https://riptutorial.com/de/home 16

Page 20: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

{ for (auto element : lst) { #pragma omp task firstprivate (element) processElement (element); } // Wait for all tasks to be finished #pragma omp taskwait } return 0; }

In diesem Beispiel wird die Verarbeitung einer STL-Liste (im Code als lst ) parallel durch die OpenMP-Task-Konstrukte #pragma omp task (mithilfe der #pragma omp task ). Das Beispiel erstellt / instanziiert eine OpenMP-Task für jedes Element in lst und die OpenMP-Threads führen die Tasks aus, sobald sie zur Ausführung bereit sind.

$ OMP_NUM_THREADS=4 ./a.out Thread 0 processing element 16 Thread 3 processing element 3 Thread 2 processing element 1 Thread 1 processing element 2 Thread 2 processing element 4 Thread 1 processing element 5 Thread 3 processing element 6 Thread 2 processing element 7 Thread 1 processing element 8 Thread 3 processing element 9 Thread 2 processing element 10 Thread 1 processing element 11 Thread 0 processing element 15 Thread 3 processing element 12 Thread 2 processing element 13 Thread 1 processing element 14

Rekursive Berechnung für Pi mit OpenMP-Aufgaben

Der folgende Code berechnet den Wert von PI mit einem rekursiven Ansatz. MAX_PARALLEL_RECURSIVE_LEVEL Wert MAX_PARALLEL_RECURSIVE_LEVEL , um zu bestimmen, bei welcher Rekursionstiefe das Erstellen von Aufgaben gestoppt wird. Mit diesem Ansatz erstellen Sie Parallelität aus rekursiven Anwendungen: Je mehr Aufgaben Sie erstellen, desto mehr parallele Aufgaben werden erstellt, desto geringer ist jedoch auch die Arbeit pro Aufgabe. Daher ist es praktisch, mit der Anwendung zu experimentieren, um zu verstehen, auf welcher Ebene die Erstellung weiterer Aufgaben keinen Nutzen für die Leistung hat.

#include <stdio.h> #include <omp.h> double pi_r (double h, unsigned depth, unsigned maxdepth, unsigned long long begin, unsigned long long niters) { if (depth < maxdepth) {

https://riptutorial.com/de/home 17

Page 21: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

double area1, area2; // Process first half #pragma omp task shared(area1) area1 = pi_r (h, depth+1, maxdepth, begin, niters/2-1); // Process second half #pragma omp task shared(area2) area2 = pi_r (h, depth+1, maxdepth, begin+niters/2, niters/2); #pragma omp taskwait return area1+area2; } else { unsigned long long i; double area = 0.0; for (i = begin; i <= begin+niters; i++) { double x = h * (i - 0.5); area += (4.0 / (1.0 + x*x)); } return area; } } double pi (unsigned long long niters) { double res; double h = 1.0 / (double) niters; #pragma omp parallel shared(res) { #define MAX_PARALLEL_RECURSIVE_LEVEL 4 #pragma omp single res = pi_r (h, 0, MAX_PARALLEL_RECURSIVE_LEVEL, 1, niters); } return res * h; } int main (int argc, char *argv[]) { #define NITERS (100*1000*1000ULL) printf ("PI (w/%d iters) is %lf\n", NITERS, pi(NITERS)); return 0; }

Unregelmäßiger OpenMP-Parallelismus online lesen: https://riptutorial.com/de/openmp/topic/6930/unregelma-iger-openmp-parallelismus

https://riptutorial.com/de/home 18

Page 22: openmp - riptutorial.com · Kapitel 1: Erste Schritte mit openmp Bemerkungen OpenMP (Open MultiProcessing) ist ein paralleles Programmiermodell, das auf Compiler-Direktiven basiert

Credits

S. No

Kapitel Contributors

1Erste Schritte mit openmp

Ani Menon, Community, Gilles, Harald, M. Chinoune, Massimiliano, takirala

2Bedingte parallele Ausführung

Harald

3Einfaches Parallelbeispiel

Gilles, Harald, Massimiliano, NoseKnowsAll, Vladimir F

4OpenMP-Reduzierungen

Gilles, Harald, meJustAndrew

5Schleifenparallelität in OpenMP

Gilles, Harald, NoseKnowsAll

6Unregelmäßiger OpenMP-Parallelismus

Harald

https://riptutorial.com/de/home 19