ParProg6a

 Documents

 11 views
of 20
All materials on our website are shared by users. If you have any questions about copyright issues, please report us to resolve them. We are always happy to assist you.
Description
6. Der OpenMP Standard ã Direktiven-basiertes API zur Programmierung von Parallelrechnern mit gemeinsamem Speicher ã für FORTRAN, C und C++ OpenMP…
Share
Transcript
6. Der OpenMP Standard • Direktiven-basiertes API zur Programmierung von Parallelrechnern mit gemeinsamem Speicher • für FORTRAN, C und C++ OpenMP Programmiermodell • OpenMP Direktiven basieren in C and C++ auf #pragma Compilerdirektiven. • Eine Direktive besteht aus einem Namen und einer Klauselliste: #pragma omp directive [clause list] • OpenMP Programme werden sequentiell Fork-Join-Modell ausgeführt, bis sie auf eine parallel Direktive Master-Thread stoßen, die eine Gruppe von Threads erzeugt: #pragma omp parallel [clause list] /* structured block */ Master-Thread Thread 1 ... Thread n • Der Thread, der die parallel Direktive ausführt, wird zum Master der Threadgruppe. Er erhält die ThreadId 0. Master-Thread 242 Beispiel: Hello World #include #include int main(int argc, char* argv[]) { printf(“Anzahl Prozessoren: %d\n“, omp_get_num_procs()); #pragma omp parallel { printf (“Thread %d von %d sagt \“Hallo Welt!\“\n“, omp_get_thread_num(), omp_get_num_threads()); } printf(“Fertig.\n“); return 0; } 243 Parallelisierung von Schleifen • Haupteinsatzgebiet von OpenMP • Jeder Thread führt den Schleifencode für eine andere Menge von Iterationen aus. Bsp: SAXPY: y = a * x + y (scalar a x plus y) for saxpy (const float a, const vector& x, const vector& y) { assert (x.size() == y.size()); #pragma omp parallel for for (int i = 0; i = end; index += inc / index -= inc > index = index + inc / - inc index = index - inc 245 Zugriff auf Variablen • Default: Alle Threads können auf alle Variablen im parallelen Codeabschnitt zugreifen. • Datenzugriffsklauseln klausel (variable, variable,...) • shared und private: von allen Threads gemeinsam oder von einem Thread privat genutzt • firstprivate und lastprivate: Initialisierung und Finalisierung der Werte privater Variablen • default: Abänderung des Defaults • reduction: gemeinsam genutzte Variablen, in denen mehrere Threads Werte akkumulieren können 246 Beispiel: Berechnung von  const double delta_x = 1.0 / num_iter; double sum = 0.0; double x, f_x; int i; #pragma omp parallel for private(x, f_x) \ shared(sum) for (i = 1; i <= num_iter; i++) { x = delta_x * (i-0.5); f_x = 4.0 / (1.0 + x*x); #pragma omp critical sum += f_x; } return delta_x * sum; 247 Pragma critical • #pragma omp critical stellt wechselseitigen Ausschluss bei der Ausführung des nachfolgenden Code-Blocks sicher => Synchronisation aller Threads => Ausbremsen paralleler Threads => effizientere Methode: Reduktionsvariablen 248 Reduktionsklausel • Die Reduktionsklausel ermöglicht die Reduktion der Werte mehrerer privater Kopien einer Variablen mittels eines Operators zu einem Wert, den die Variable beim Verlassen des parallelen Blocks im Master erhält. • Die Klausel hat die Gestalt: reduction (operator: variable list). • Die Variablen in der Liste werden implizit als privat festgelegt. • Mögliche Operatoren sind: +, *, &, |, ^, &&, ||. Beispiel: #pragma omp parallel reduction(+: sum) num_threads(8) { /* compute local sums here */ } /*sum here contains sum of all local instances of sums */ 249 Beispiel: Berechnung von  mit Reduktion const double delta_x = 1.0 / num_iter; double sum = 0.0; double x, f_x; int i; #pragma omp parallel for private(x, f_x) \ reduction(+: sum) for (i = 1; i <= num_iter; i++) { x = delta_x * (i-0.5); f_x = 4.0 / (1.0 + x*x); sum += f_x; } return delta_x * sum; 250 Reduktionsoperatoren Operator Bedeutung Typen Neutrales Element + Summe float, int 0 * Produkt float, int 1 & bitweises Und int alle Bits 1 | bitweises Oder int 0 ^ bitweise XOR int 0 && Logisches Und int 1 || Logisches Oder int 0 251 Initialisierung von privaten Variablen • Private Variablen sind beim Eintritt und beim Verlassen eines parallelen Abschnitts undefiniert. • Die Klausel firstprivate dient dazu, private Variablen mit dem Wert der Variablen im Masterthread zu initialisieren. • Die Initialisierung erfolgt nur einmal pro Thread und nicht z.B. einmal pro Schleifendurchlauf in einer parallelen Schleife. Beispiel: x[0] = complex_function(); #pragma omp parallel for private(j) firstprivate(x) for (i=0; i PThreads 259 Datenabhängigkeiten • notwendige Voraussetzung für Parallelisierung: wechselseitige Unabhängigkeit der Ergebnisse der einzelnen Iterationen einer Schleife • Seien zwei Anweisungen A1 und A2 gegeben, wobei A1 in der sequentiellen Ausführung vor A2 liege. • echte Datenabhängigkeit (Flussabhängigkeit, RAW- read after write) A1 schreibt in eine Speicherzelle, die von A2 gelesen wird. • Gegenabhängigkeit (WAR – write after read) A1 liest eine Speicherzelle, die anschließend von A2 geschrieben wird. • Ausgabeabhängigkeit (WAW – write after write) A1 und A2 schreiben in dieselbe Speicherzelle. 260
Similar documents
We Need Your Support
Thank you for visiting our website and your interest in our free products and services. We are nonprofit website to share and download documents. To the running of this website, we need your help to support us.

Thanks to everyone for your continued support.

No, Thanks