Einführung in das parallele Programmieren mit und Java Seite 1
Übersicht Parallele Prozesse und Erste Schritte mit Kollektive Kommunikation Weitere Möglichkeiten Seite 2
Literatur (1) Homepage des 2-Forums http://www.mpi-forum.org/ -Spezifikations-Dokumente (auch zum Nachschlagen gut geeignet) Als html- und Postscript-Datei Seite 3
Literatur (2) mpijava Home Page http://www.hpjava.org/mpijava.html Spezifikation von mpijava Seite 4
Literatur (3) Marc Snir, Steve Otto, Steven Huss-Lederman, David Walker, Jack Dongarra:. The Complete Reference Vol. 1: The core. Second edition. 350 Seiten - MIT Press Von den Autoren des -Standards. Lehnt sich stark an das Spezifikations-Dokument an (teilweise wortgleich, teilweise ausführlicher). Die 1. Auflage gibt es auch als html- oder Postscript-Datei. Seite 5
Literatur (4) William Gropp, Ewing Lusk, Anthony Skjellum: Using The MIT Press, Cambridge, London 1999 William Gropp, Ewing Lusk, Rajeev Thakur Using -2 The MIT Press Cambridge, London 2000 Seite 6
Literatur (5) Peter S. Pacheco A User s Guide to 51 Seiten Seite 7
Literatur (6) Eine erweiterte Version dieses Dokuments gibt es auch als Buch. Peter Pacheco: Parallel Programming With 440 Seiten - Morgan Kaufmann Publishers Seite 8
Literatur (7) Parallele Programmierung mit - ein Praktikum Thomas Worsch/Peter Sanders 152 Seiten, 1997 Preis: 17,90 EUR ISBN 3-931216-76-4 Seite 9
Parallele Prozesse und Seite 10
Gemeinsamer Speicher P 1 gemeinsamer P 2 Speicher a=4 c=3+a a Seite 11
Explizite Kommunikation P 1 lokaler P 2 Speicher a empfangen c=3+a a=4 a senden a a Seite 12
Message Passing Datenaustausch bei gemeinsamem Speicher (shared memory): Standard: OpenMP Datenaustausch bei lokalem Speicher (distributed memory) und expliziter Kommunikation (message passing) Standard: Seite 13
(Message Passing Interface) ist eine Bibliothek (C, Fortran, C++), mit der die explizite Kommunikation abgewickelt werden kann. (Genauer: definiert einen Standard für solche Bibliotheken.) Es gibt auch eine inofizielle Java-Version. Vorteile bei Einsatz von : hohe Übertragungsleistung durch optimierte Implementierungen alternativ: frei verfügbare Implementierungen Portabilität auch bei gemeinsamem Speicher möglich viele -basierte Bibliotheken verfügbar Seite 14
-Versionen -Versionen: Befehle: Version 1.0 (1994): Unterstützung von Fortran77 und C. Version 1.1 (1995): Berichtigungen und Klarstellungen, kleine Änderungen. Version 1.2 (1997): Weitere Berichtigungen und Klarstellungen. Version 2.0 (1997): Wesentliche Erweiterungen: Einseitige Kommunikation, -IO, dynamische Generierung von Tasks, Unterstützung von Fortran 90 und C++ Mächtig und komplex 129 0 1 193 323 Seite 15
Lernaufwand ist einfach: viele -Programme nutzen nur 10-20 Befehle. Zum einfachen Arbeiten mit sind 6 Befehle ausreichend. Mit 4 weiteren kann man schon ziemlich viel machen Inhalt dieses Kurses: Start-Paket, wesentliche Konzepte einige Hinweise auf weitere -Funktionalität Seite 16
Erste Schritte mit in Java Seite 17
Hello, world import mpi.*; public class _HelloWorld { public static void main(string[] args) { System.out.println("Hello, world"); } } Programm javac _HelloWorld.java prunjava 4 _HelloWorld Eingabe Hello, world Hello, world Hello, world Hello, world Ausgabe Seite 18
Zweck der -Befehle Programm wird 4 mal gestartet und produziert 4 mal das gleiche Ergebnis Es fehlt noch: Die Prozesse müssen miteinander kommunizieren. Sie müssen sich gegenseitig identifizieren können. Sich müssen sich untereinander synchronisieren. Befehle Seite 19
Theorie: Was ist ein Kommunikator? Ein -Kommunikator ist eine Datenstruktur (Objekt), über die die Kommunikation zwischen den Prozessen abgewickelt wird. umfasst Gruppe von Prozessen Alle diese Prozesse besitzen eine Kopie dieses Kommunikators Markierung (tag) Jede Nachricht gehört zu einem bestimmten Kommunikator In Java und C++: Methoden zum Senden und Empfangen. Seite 20
Klassen für Kommunikatoren Comm Intercomm Intracomm Graphcomm Cartcomm Keine Unterscheidung innerhalb des Kurses Vordefinierte Kommunikatoren:.COMM_WORLD.COMM_SELF Umfasst alle gestarteten Prozesse Umfasst nur den Prozess selbst Seite 21
10 grundlegende Befehle.Init,.Finalize Initialisieren/ Deinitialisieren <Comm>.Size, <Comm>.Rank <Comm>.Send, <Comm>.Recv Identifikation Senden und Empfangen (point to point communication) <Intracomm>.Scatter, <Intracomm>.Gather, <Intracomm>.Bcast, <Intracomm>.Reduce Kollektive Kommunikation Seite 22
import mpi.*; public static void main(string[] args) throws Exception { int size; int my_rank; Erstes Beispielprogramm.Init(args); size =.COMM_WORLD.Size(); rank =.COMM_WORLD.Rank(); System.out.println("I am process "+rank+" out of "+ size); }.Finalize(); Seite 23
Ausgabe SUNOS:sunc00:mpi_kurs[19]$ prunjava 4 1 I am process 2 out of 4I am process 0 out of 4 I am process 1 out of 4 I am process 3 out of 4 SUNOS:sunc00:mpi_kurs[20]$ prunjava 4 1 I am process 3 out of 4I am process 2 out of 4 I am process 1 out of 4 I am process 0 out of 4 SUNOS:sunc00:mpi_kurs[22]$ mprun -np 4 hw.out I am process I am process 01 out of 4<CR> I am process 2 out of 4I am process out of 4<CR> <CR> 3 out of 4<CR> Seite 24
Beispiel 2: Senden und Empfangen Master-Prozess: rank 0 Worker-Prozesse: rank 1.. (size-1) Jeder Worker-Prozess sendet count Messages mit den Zahlen 1.. count an den Master-Prozess. Der Master-Prozess empfängt alle Messages und gibt sie auf dem Bildschirm aus Seite 25
Ausgabe SUNOS:sunc00:mpi_kurs[51]$ prunjava 3 2 1: Received 1. Message from Process 1 2: Received 1. Message from Process 3 3: Received 2. Message from Process 1 4: Received 1. Message from Process 2 5: Received 2. Message from Process 3 6: Received 3. Message from Process 1 7: Received 2. Message from Process 2 8: Received 3. Message from Process 3 9: Received 3. Message from Process 2 Seite 26
Source-Code (1) import mpi.*; public static void main(string[] args) throws Exception { int size, my_rank; int count = 3;.Init(args); size =.COMM_WORLD.Size(); my_rank =.COMM_WORLD.Rank(); Seite 27
} if (my_rank!=0) { //Worker int[] sbuf = new int[1]; for (sbuf[0]=1; sbuf[0]<=count; sbuf[0]++) { } Seite 28.COMM_WORLD.Send(sbuf, 0, 1,.INT, 0, 0); } else { } int[] rbuf = new int[1]; for (int i=1; i<=count*(size-1); i++) { } Status st =.COMM_WORLD.Recv(rbuf, 0, 1,.INT,.ANY_SOURCE,.ANY_TAG); System.out.println(my_rank+": Received "+rbuf[0]+.finalize(); Source-Code (2) ". message from process "+st.source);
Grundtypen C -Typ (C-Typ) _CHAR (signed char) _SHORT (signed short int) _INT (signed int) _LONG (signed long int) _UNSIGNED_CHAR (unsigned char) _UNSIGNED_SHORT (unsigned short int) _UNSIGNED (unsigned int) _UNSIGNED_LONG (unsigned long int) _FLOAT (float) _DOUBLE (double) _LONG_DOUBLE (long double) _BYTE _PACKED Java -Typ (Java-Typ).BYTE (byte).char (char).short (short).boolean (boolean).int (int).long (long).float (float).double (double).object (Object).PACKED Seite 29
Deadlock Send Receive P 2 Send Send Receive Receive P 1 P 3 Send Send P 0 P 4 Receive Receive Send P 7 P 5 Send Receive Receive P 6 Send Receive Seite 30
Serialisierung Send Receive P 2 Send Send Receive Receive P 1 P 3 Send Receive P 0 P 4 Receive Send Send P 7 P 5 Send Receive Receive P 6 Send Receive Seite 31
Kollektive Kommunikation Seite 32
_Barrier <Intracomm>.Barrier(): Prozesse dürfen erst dann weitermachen, wenn alle Prozesse des Kommunikators diese Stelle erreicht haben. Wird normalerweise nicht gebraucht. Sämtliche Synchronisation sollte automatisch mit den Befehlen zur Datenkommunikation erledigt werden. Seite 33
_Bcast <Intracomm>.Bcast: Verteilt einen einzigen Datensatz auf alle Prozesse (einschließlich des eigenen). a Broadcast a a a Seite 34
_Scatter und _Gather <Intracomm>.Scatter: Verteilt ein Feld von Datensätzen auf alle Prozesse, etwa wie beim Austeilen von Karten. a c b Scatter Gather a b c <Intracomm>.Gather: Die Umkehrung von Scatter. Sammelt die Daten (in der richtigen Reihenfolge) wieder ein. Seite 35
_Reduce <Intracomm>.Reduce: Die Daten werden wie bei _Gather gesammelt, jedoch nicht in einem Feld abgelegt, sondern zu einem einzigen Datensatz verknüpft. Seite 36
Reduzierungs-Operationen Bei <Intracomm>.Reduce sind verschiedene Reduzierungs- Operationen möglich (+selbstdefinierte):.max,.min,.sum,.prod,.land (logical and),.band (bitwise and),.lor,.bor,.lxor,.bxor,.maxloc,.minloc (liefert Maximum/Minimum und den Rank des entsprechenden Prozesses). Seite 37
_Reduce mit _SUM <Intracomm>.Reduce mit op=.sum würde einem <Intracomm>.Gather mit anschließender Aufsummierung der Feldelemente entsprechen. a Reduce a a+b+c b b c c Seite 38
Andere kollektive Operationen Es gibt noch andere kollektive Operationen, in denen die Daten von vielen Prozessen an viele Prozesse verteilt werden. (<Intracomm>.Allgather, <Intracomm>.Alltoall, <Intracomm>.Reduce_scatter) Seite 39
Weitere Möglichkeiten Übertragung komplexer Datentypen (Strings, Objekte) Übertragung nichtkontinuierlicher Elemente eines Felds Seite 40
Weitere Möglichkeiten Ordnen der Prozesse in einer Topologie (0,0) (0,1) (0,2) (1,0) (1,1) (1,2) (2,0) (2,1) (2,2) Seite 41
Möglichkeiten aus 2 Dynamisches Starten von neuen Prozessen Einseitige Kommunikation (Programmierung fast wie bei gemeinsamem Speicher). Parallele I/O mit C++ Seite 42