message passing interface (mpi) - wi1.uni- · pdf filewestfälische...

25
Westfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele und Verteilte Programmierung“ Julian Pascal Werra Themensteller: Prof. Dr. Herbert Kuchen Betreuer: Dipl.-Wirt.-Inform. Philipp Ciechanowicz Institut für Wirtschaftsinformatik Praktische Informatik in der Wirtschaft

Upload: vannhu

Post on 06-Feb-2018

226 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Westfälische Wilhelms-Universität Münster

Ausarbeitung

Message Passing Interface (MPI)

Im Rahmen des Seminars „Parallele und Verteilte Programmierung“

Julian Pascal Werra

Themensteller: Prof. Dr. Herbert Kuchen Betreuer: Dipl.-Wirt.-Inform. Philipp Ciechanowicz Institut für Wirtschaftsinformatik Praktische Informatik in der Wirtschaft

Page 2: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

II

Inhaltsverzeichnis

1 Motivation.................................................................................................................. 3

2 Parallele und Verteilte Programmierung ................................................................... 4

2.1 Klassifizierung von Parallelrechnern................................................................ 4

2.2 Verteilter und gemeinsamer Speicher............................................................... 5

3 MPI ............................................................................................................................ 6

3.1 Das Message Passing Programmiermodell....................................................... 6

3.2 Grundlagen........................................................................................................ 6

3.3 Vergleich MPI / OpenMP................................................................................. 8

3.4 Kommunikation ................................................................................................ 8

3.4.1 Prozessgruppen und Kommunikatoren......................................................... 9 3.4.2 Einzeltransfer-Operationen......................................................................... 12 3.4.3 Globale Kommunikations-Operationen...................................................... 15

3.5 Zeitmessung (Benchmarking)......................................................................... 20

3.6 Prozesstopologien ........................................................................................... 21

4 Fazit ......................................................................................................................... 22

A Quelltexte................................................................................................................. 23

Literaturverzeichnis ........................................................................................................ 24

Page 3: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 1: Motivation

3

1 Motivation

Seit Mitte der 1980er Jahre gab es unter Anderem zwei für das Thema parallele und

verteilte Programmierung bedeutende technologische Fortschritte:

• Hardware (im Besonderen Prozessoren) ist günstiger und leistungsfähiger

geworden

• Entwicklung von Hochgeschwindigkeitsnetzwerken (z.B. LAN)

Diese beiden Entwicklungen führten dazu, Parallelrechner zu entwickeln, die

grundlegend als „eine Ansammlung von Berechnungseinheiten (Prozessoren), die durch

koordinierte Zusammenarbeit große Probleme schnell lösen können“ [RR00, S.17]

beschrieben werden können. Die Vorteilhaftigkeit eines solchen Systems liegt unter

Anderem in der einfachen Skalierbarkeit, der Redundanz (ständige Verfügbarkeit),

sowie im preislichen Vorteil gegenüber einem Super-Computer.

Diese Seminararbeit beschäftigt sich mit dem Message Passing Interface (MPI), einem

momentan dominierenden Standard zum Nachrichtenaustausch bei parallelen

Berechnungen auf Systemen mit verteiltem Speicher.

Die Arbeit ist in zwei Kapitel gegliedert. Kapitel 2 führt in die Grundlagen paralleler

Berechnungen ein und klassifiziert die Varianten von Parallelrechnern und die

möglichen Speicherstrukturen. Das Kapitel 3 gibt anschließend anhand der MPI-

Spezifikation einen tieferen Einblick in die parallele Programmierung auf Systemen mit

verteiltem Speicher. Der Vollständigkeit halber wird zudem am Beispiel OpenMP ein

Vergleich mit einem Äquivalent für Systeme mit gemeinsamem Speicher angestellt.

Page 4: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 2: Parallele und Verteilte Programmierung

4

2 Parallele und Verteilte Programmierung

2.1 Klassifizierung von Parallelrechnern

Parallelrechner werden üblicherweise in vier Klassen (Flynnsche Klassifizierung)

aufgeteilt, deren Charakterisierung nach den Merkmalen „globale Kontrolle“ und den

„resultierenden Daten- und Kontrollflüssen“ erfolgt [RR00, S.18]:

• SISD – Single Instruction, Single Data

o ein Prozessor mit Zugriff auf je einen Daten- und Programmspeicher.

Einprozessorsysteme

• MISD – Multiple Instruction, Single Data

o mehrere Prozessoren mit Zugriff auf einen gemeinsamen Datenspeicher

und je einen eigenen Programmspeicher. Jeder Prozessor erhält dasselbe

Datum aus dem Datenspeicher.

wenig sinnvoll. Die Klasse existiert in der Praxis nicht

• SIMD – Single Instruction, Multiple Data

o mehrere Prozessoren mit Zugriff auf einen gemeinsamen Daten- und

Programmspeicher. Alle Prozessoren arbeiten dieselbe Instruktion

gleichzeitig, d.h. synchron ab (Datenparallelität).

Vektor- und Feldrechner

• MIMD – Multiple Instruction, Multiple Data

o mehrere Prozessoren mit Zugriff auf einen gemeinsamen Datenspeicher

und je einen eigenen Programmspeicher. Jeder Prozessor erhält ein

separates Datum aus dem Datenspeicher.

alle Arten von Multiprozessorsystemen

Für uns relevant ist lediglich die vierte Klasse (MIMD), da sie ein System von

Prozessoren mit jeweils eigenem Programmspeicher definiert.

Page 5: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 2: Parallele und Verteilte Programmierung

5

Abb. 2-1.1

Der generelle Ablauf eines MIMD-Verarbeitungsschrittes sieht vor, dass jeder

Prozessor einen Instruktionsschritt aus seinem Programmspeicher auf ein aus dem

Datenspeicher geladenes Datum ausführt und eventuelle Ergebnisse in den

Datenspeicher zurück schreibt. Genauere Erläuterungen zu den übrigen Klassen finden

sich in [RR00, S.17ff].

2.2 Verteilter und gemeinsamer Speicher

Es soll nun eine weitere Unterteilung dieser Klasse vorgenommen werden, da

heutzutage zwar viele Parallelrechner nach MIMD arbeiten, sich aber in der

Speicherorganisation unterscheiden. Hierbei wird grundlegend zwischen Rechnern mit

verteiltem Speicher (distributed memory machine - DMM) und jenen mit gemeinsamem

Speicher (shared memory machine - SMM) unterschieden. Darüber hinaus existiert

noch eine Mischform, die als virtuell gemeinsamer Speicher bezeichnet wird, hier aber

vernachlässigt wird.

Hierbei wird zwischen zwei Ebenen unterschieden, wobei die erste die physikalische

Speicherstruktur betrachtet, die zweite hingegen die Sicht des Programmierers abbildet.

Der Einfachheit halber betrachten wir nur die physikalische Ebene und setzen voraus,

dass die Speicherstruktur auf Programmierebene nicht von der physikalischen abweicht.

Das Hauptaugenmerk wird auf den verteilten Speicher gelegt, da der MPI-Standard für

solche Systeme konzipiert wurde. Der Vollständigkeit halber wird aber im Kapitel 3.3

ein Vergleich zwischen den beiden Strukturvarianten angestellt.

Es sei vorweggenommen, dass ein solches System, da es keinen gemeinsamer Speicher

gibt, auf Nachrichtenaustausch zwischen den Prozessen angewiesen ist. Näheres hierzu

folgt im nächsten Kapitel.

Page 6: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

6

3 MPI

3.1 Das Message Passing Programmiermodell

Das Message Passing Programmiermodell sieht eine Kollektion von Prozessoren mit

jeweils einem eigenem lokalem Speicher vor, was einem System der Klasse MIMD mit

einer DMM Speicher-Struktur entspricht. Der notwendige Nachrichtenaustausch erfolgt

über ein Netzwerk, mit dem jedes Einzelsystem verbunden sein muss. Um welche Form

von Netzwerk es sich handelt ist für uns vorerst nicht von Bedeutung, kann aber bei der

Analyse von Geschwindigkeit und Zuverlässigkeit eine große Rolle spielen.

Abb. 3-1.1

3.2 Grundlagen

MPI ist eine Spezifikation, die beschreibt wie Nachrichten bei parallelen Berechnungen

auf verteilten Systemen (verteilter Speicher) ausgetauscht werden. Dabei legt MPI

Programm-Bindings (Sprachkonstrukte) fest, die für in C oder FORTRAN geschriebene

Programme definiert sind. Sämtliche hier vorgestellten Funktionen und Beispiel-

Quelltexte sind in der Sprache C geschrieben. Kurz gefasst ist MPI also eine Bibliothek

zur Parallelprogrammierung für nachrichtengekoppelte Systeme.

1997 wurde im Zuge einer Erweiterung der bisherigen MPI-Spezifikation MPI-1, die

seit 1994 besteht und mittlerweile in Version 1.2 vorliegt, eine um dynamische

Prozessverwaltung, parallele Ein-/Ausgabe und einseitige Kommunikationsoperationen

erweiterte Spezifikation MPI-2 vorgeschlagen. MPI-2 stellt eine Obermenge von MPI-1

dar, somit ist jedes gültige MPI-1-Programm auch ein gültiges MPI-2-Programm. Im

Zuge der Einführung durch diese Ausarbeitung werden keine der durch MPI-2

gegebenen Erweiterungen benötigt. Somit wird auch nicht weiter auf Unterschiede der

beiden Spezifikationen eingegangen und im Allgemeinen einfach von MPI gesprochen.

Im Folgenden ist unter dem Begriff MPI-Programm ein C/FORTRAN-Programm mit

MPI-Aufrufen zu verstehen.

Page 7: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

7

Grundsätzlich sind MPI-Programme portabel, sprich unabhängig vom physikalisch

vorliegenden System nutzbar. Dies wird durch die einheitlichen Schnittstellen

sichergestellt.

In den folgenden Kapiteln wird zuerst in die wichtigsten Kommunikationsoperationen

eingewiesen. Anschließend wird, von diesen Grundlagen ausgehend, auf einige

speziellere Themen eingegangen. Dieses Kapitel soll somit in Basis-Wissen von MPI

einführen und einige wichtige Themen aufgreifen, die für die Erstellung eines MPI-

Programms essentiell sind.

Einige Erläuterungen werden zum Verständnis von Beispiel-Quelltexten begleitet. Zur

Vorbereitung wird deshalb kurz die Ausführung eines MPI-Programms aus Benutzer-

Sicht erläutert.

Kompiliert wird der Quelltext mit dem Befehl

mpicc –o runnable example.c,

wobei example.c die Quelltext-Datei angibt und runnable den Namen der

kompilierten Datei definiert. Das anschließende Ausführen des Programms geschieht

per

mpirun –np 5 runnable.

Über den Parameter –np wird festgelegt wie viel Prozesse für die Ausführung erstellt

werden sollen, im obigen Beispiel sind es fünf.

Zum Aufbau eines MPI-Programms sei gesagt, dass die Funktion MPI_Init(&argc,

&argv) stets die erste aufgerufene MPI-Funktion sein muss. Die Parameter entsprechen

den vom Programm beim Start entgegengenommenen. Die Funktion erlaubt dem

System entsprechende Vorbereitungen für die Arbeit mit der MPI-Bibliothek

vorzunehmen. Entsprechend gibt es eine äquivalente Funktion MPI_Finalize(),

welche das System nach Beendigung aller MPI-Operationen dazu veranlasst, die

genutzten Ressourcen wieder freizugeben.

Mit [CH00] und [LA00] seien zwei kostenlose Distributionen zur MPI-Programmierung

genannt.

Page 8: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

8

3.3 Vergleich MPI / OpenMP

Vor der weiteren Einführung in MPI werden kurz einige Unterschiede und

Gemeinsamkeiten zwischen Systemen mit verteiltem und gemeinsamem Speicher

erklärt. Für diesen Vergleich wird OpenMP herangezogen, da es einer der

Hauptvertreter für parallele Programmierung auf Systemen mit gemeinsamem Speicher

ist aber auch in Kombination mit MPI angewandt werden kann.

Während MPI zur Parallelisierung auf Nachrichtenaustausch zurückgreift, kann auf

einem System mit gemeinsamem Speicher auf Schleifen- oder Thread-Ebene

parallelisiert werden. OpenMP stellt eine Spezifikation für Thread-basierte

Parallelisierung dar. Hierbei wird nach dem fork-join-Prinzip gearbeitet, sprich ein von

vornherein bestehender Master-Thread führt das Programm so lange aus, bis ein parallel

auszuführender Programmteil auftaucht, welcher über einen vom Programmierer

angelegten Anweisungsblock explizit als solcher gekennzeichnet ist. Der Master erzeugt

nun ein Team von Threads (fork), die unter seiner Leitung den entsprechenden

Programmteil bearbeiten. Alle Threads arbeiten auf demselben Datenspeicher, eine

Änderung durch einen Thread ist also sofort für alle anderen, auch für Threads

außerhalb des Teams, sichtbar. Ein Nachrichtenaustausch ist hier somit nicht nötig.

Haben die Threads ihre Arbeit erfolgreich beendet, erfolgt der join, d.h. die erzeugten

Threads werden synchronisiert und anschließend beendet; lediglich der Master läuft

weiter.

Wie bereits erwähnt können MPI und OpenMP auch in Verbindung miteinander genutzt

werden. Dies ist vor allem dann sinnvoll, wenn mehrere Shared-Memory-Clients zu

einem Cluster zusammengeschlossen sind. Hier kann innerhalb eines Clients mit

OpenMP gearbeitet und zum Nachrichtenaustausch mit anderen Clients auf MPI

zurückgegriffen werden.

Ein tieferer Einblick in OpenMP bleibt an dieser Stelle aus, als Literatur für weitere

Recherche sei aber [RR00, S.273ff] oder [OP00] empfohlen.

3.4 Kommunikation

Wie bereits erwähnt, sind parallele Prozesse auf Systemen ohne gemeinsamen Speicher

darauf angewiesen Nachrichten über ein Netzwerk miteinander austauschen zu können.

Dieses Kapitel erläutert die Funktionsweise des Nachrichtenaustauschs mit MPI. Dabei

Page 9: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

9

wird zuerst auf die generellen Rahmenbedingungen eingegangen unter denen Prozesse

kommunizieren können. Anschließend werden konkrete Punkt-zu-Punkt- und globale

Kommunikations-Operationen eingeführt.

3.4.1 Prozessgruppen und Kommunikatoren

Unter einer Prozessgruppe versteht sich eine Menge von geordneten, also durch so

genannte Ränge fortlaufend nummerierten Prozessen. Solche Gruppen sind besonders

interessant, wenn es um die Realisierung taskparalleler Programme geht, worunter man

Programme versteht, in denen verschiedene Programmteile unabhängig voneinander

und somit parallel, ausgeführt werden können. Prozessgruppen sind nicht zwingend

überschneidungsfrei, ein Prozess kann somit mehreren Prozessgruppen angehören und

hat innerhalb dieser jeweils einen gruppenspezifischen Rang. Jede Kommunikation

findet innerhalb eines Kommunikationsgebietes statt, welches lokal durch so genannte

Kommunikatoren dargestellt wird.

Prozesse können also eindeutig identifizierbar in Prozessgruppen zusammengefasst

werden und anhand des der Prozessgruppe zugeordneten Kommunikators miteinander

Nachrichten austauschen. Im Folgenden soll nun ein kurzer Einblick in die durch MPI

gegebenen Operationen für Prozessgruppen und Kommunikatoren gegeben werden.

Innerhalb der Kommunikatoren muss zwischen Inter- und Intra-Kommunikatoren

unterschieden werden. Mit den zuerst genannten lassen sich Punkt-zu-Punkt-

Kommunikationen zwischen zwei Prozess-Gruppen realisieren. Letztere erlauben die

Kommunikation der Prozesse einer Gruppe untereinander. Im Folgenden ist stets der

Intra-Kommunikator gemeint, die Kommunikation zwischen verschiedenen

Prozessgruppen wird hier nicht weiter behandelt.

Standardmäßig kann der vordefinierte Kommunikator MPI_COMM_WORLD genutzt

werden, der alle laufenden Prozesse miteinander kommunizieren lässt. Möchte man

allerdings die Möglichkeiten der Prozessgruppen nutzen, bietet es sich an eigene

Kommunikatoren zu definieren, die entweder auf bereits bestehenden Gruppen basieren

können, oder auch vorerst für sich allein gestellt angelegt werden können.

Möchte man eine Prozessgruppe erstellen, nutzt man je nach Zweck eine der in der

folgenden Erläuterung aufgeführten Funktionen

Page 10: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

10

Die ersten drei Funktionen, die sich allesamt mit Mengenbildung zweier bestehender

Gruppen beschäftigen, benötigen die drei Parameter

MPI_Group g1, MPI_Group g2, MPI_Group *ng,

womit die zwei zu vermengenden Gruppen (g1 und g2) und die Zielgruppe (ng)

definiert werden.

Vereinigung zweier Gruppen g1 und g2 in eine neue Gruppe ng

int MPI_Group_union ( ... )

Schnittmengenbildung zweier Gruppen g1 und g2 in eine neue Gruppe ng

int MPI_Group_intersection ( ... ) Differenzmengenbildung zweier Gruppen g1 und g2 in eine neue Gruppe ng

int MPI_Group_difference ( ... ) Neben dem Vermengen von Gruppen stehen auch Funktionen zur Verfügung, die

Änderungen innerhalb einer Gruppe vornehmen können und folgende Parameter

verlangen:

MPI_Group g1, int p, int *ranks, MPI_Group *ng

Hierbei ist g1 wieder die zu betrachtende und ng die neu zu erstellende Gruppe. ranks

zeigt auf ein p-elementiges Array von Integern, welches die betroffenen Prozesse-

Indizies der bestehenden Gruppe angibt.

Die durch ranks indizierten Prozesse werden nun entweder in eine neue Gruppe

gepackt (Untermenge)

int MPI_Group_( ... ),

oder es wird eine neue Gruppe erzeugt, die alle nicht in ranks aufgeführten Prozesse

beinhaltet (Löschen)

int MPI_Group_excl( ... ),

Page 11: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

11

Darüber hinaus bietet MPI Funktionen an, die Informationen über eine Prozessgruppe

liefern können. So lässt sich zum Beispiel die Größe (Anzahl der Prozesse) einer

Gruppe bestimmen. Das Ergebnis wird in size zurückgeliefert:

int MPI_Group_size ( MPI_Group group, int *size )

Entsprechend findet auch die Bestimmung des Indizes des aufrufenden Prozesses statt,

deren Ergebnis in rank zurückgeliefert wird:

int MPI_Group_rank ( MPI_Group group, int *rank )

Außerdem ist eine Gleichheitsprüfung zweier Gruppen möglich:

int MPI_Group_compare ( MPI_Group g1, MPI_Group g2, int *res )

Hierbei wird für res zwischen drei möglichen Rückgabewerten für identisch,

gleichartig (gleiche Prozesse, aber unterschiedliche Reihenfolge) und ungleich

unterschieden wird

Zu guter Letzt kann eine Gruppe über die Anweisung MPI_Group_free(MPI_Group

*group) wieder freigegeben werden.

Die drei genannten, Informationen liefernden Funktionen, sowie die Freigabe-Funktion

sind entsprechend auch für Kommunikatoren definiert (MPI_Comm_size,

MPI_Comm_rank, MPI_Comm_compare, MPI_Comm_free) und werden hier nicht

nochmals erläutert. Wichtig ist lediglich, dass hier Prozesse betroffen sind, die einer

dem Kommunikator zugeordneten Prozessgruppe angehören.

Einem Kommunikator eigen sind allerdings drei Funktionen, die das Erstellen, das

Duplizieren oder das Splitten eines solchen zur Aufgabe haben.

Die Erzeugung eines Kommunikators wird durch folgenden Aufruf erreicht:

int MPI_Comm_create ( MPI_Comm comm, MPI_Group group, MPI_Comm *ncomm )

Zum Einen muss group eine Teilmenge einer zum Kommunikator comm gehörenden

Gruppe sein, zum Anderen muss die Funktion von alle beteiligten Prozessen mit dem

selben Gruppen-Argument aufgerufen werden, damit diese einen Zeiger ncomm auf den

neuen Kommunikator erhalten. Alle Prozesse, die zwar einen Kommunikator teilen,

aber nicht zur durch group definierten Teilmenge gehören erhalten MPI_COMM_NULL

als Hinweis darauf, dass sie keinen neuen Kommunikator zugewiesen bekommen.

Page 12: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

12

Das Duplizieren eines Kommunikators ist vergleichsweise simpel und enthält lediglich

zwei Argumente für den bestehenden und den neu zu erstellenden Kommunikator. Die

zugeordnete Gruppe und Topologie bleibt dabei erhalten, das Kommunikationsgebiet

allerdings ist ein neues.

int MPI_Comm_dup ( MPI_Comm comm, MPI_Comm *ncomm )

Zur Aufspaltung eines Kommunikators steht ebenfalls eine Funktion zur Verfügung:

int MPI_Comm_split ( MPI_Comm comm, int color, int key, MPI_Comm *ncomm )

Dabei werden die Prozesse der dem Kommunikator comm zugeordneten Prozessgruppe

in disjunktive Teilgruppen unterteilt. Dabei wird über den Parameter color die

Zugehörigkeit definiert, Prozesse die für color denselben Wert angeben, werden also

derselben neuen Untergruppe zugeteilt, wobei die Reihenfolge innerhalb der Gruppe

durch key festgelegt ist. Jeder beteiligte Prozess erhält in ncomm einen Zeiger auf den

Kommunikator der neuen Teilgruppe.

Näheres zu diesem Thema findet sich in [RR00, S197ff].

3.4.2 Einzeltransfer-Operationen

An einem Einzeltransfer (Punkt-zu-Punkt-Kommunikation) sind immer genau zwei

Prozesse in einer klassischen Sender-Empfänger-Beziehung beteiligt. Zur Durchführung

ist von beiden Prozessen die Ausführung von entsprechenden

Kommunikationsanweisungen nötig. Hierfür definiert MPI drei Funktionen. Zuerst sei

die Sendeoperation

int MPI_SEND( void *smessage, int count, MPI_Datatype type, int dest, int tag,

MPI_Comm comm )

genannt, welche eine Nachricht der Größe count und des Typs type aus dem

Sendepuffer smessage an den Prozess mit dem Index dest schickt, der sich innerhalb

des durch comm definierten Kommunikationsgebietes befindet. Zur Unterscheidung von

mehreren Nachrichten desselben Senders dient der Parameter tag als Markierung.

Page 13: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

13

Entsprechend existiert eine Empfangsoperation

int MPI_RECV( void *rmessage, int count, MPI_Datatype type, int source, int tag, MPI_Comm comm, MPI_Status *status ),

die eine Nachricht vom Prozess mit dem Index source entgegennimmt, der durch die

Angabe von MPI_ANY_SOURCE aber nicht direkt bekannt sein muss. Der Parameter

status enthält Informationen über die empfangene Nachricht. Die übrigen Parameter

korrespondieren mit denen der Sendeoperation. Im Anhang A findet sich das Beispiel

QT01, welches eine einfache Nachrichtenübertragung abbildet.

Die dritte Funktion MPI_Sendrecv(...) ist eine Mischoperation zum

Senden/Empfangen von Nachrichten und enthält somit alle für das Senden und

Empfangen notwendigen Parameter aus den bereits bekannten Funktionen. Da diese

bereits besprochen wurden, werden sie hier nicht nochmals aufgeführt. Sollte man

allerdings nur einen Puffer für das Senden/Empfangen zur Verfügung haben, muss man

auf die Funktion MPI_Sendrecv_replace(...) ausweichen, die lediglich einen

Puffer als Parameter erwartet.

Wichtig ist hier, dass grundsätzlich jeder Prozess mit jedem anderen kommunizieren

kann. Wie erwähnt, muss der Sender den Empfänger dabei allerdings kennen, der

Empfänger hingegen kann Nachrichten auch von unbekannten Gesprächspartnern

entgegennehmen.

MPI_SEND und MPI_RECV sind so genannte blockierende Operationen, dass heißt sie

können unabhängig voneinander aufgerufen werden und müssen notfalls aufeinander

warten. Dabei blockieren sie jeweils den aufrufenden Prozess. Tatsächlich hängt das

Verhalten von der konkreten Implementierung ab, wobei meist eine der folgenden

Möglichkeiten angewandt wird:

• Die Nachricht wird ohne Zwischenspeicherung verschickt. Der Sender muss

warten bis der Empfänger die Nachricht entgegennimmt.

• Die Nachricht wird im Systempuffer des Senders gespeichert und kann vom

Empfänger dort abgerufen werden. Der Sender blockiert somit nur kurz,

Page 14: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

14

allerdings setzt diese Methode somit zusätzlichen Speicher voraus und nimmt

zusätzliche Zeit für das Kopieren in den Puffer in Kauf.

Näheres wird im Laufe des Kapitels in der Thematik Übertragungsmodi erarbeitet.

Bei der Verwendung dieser beiden Operationen kann es unter Umständen zu

Verklemmungen (Deadlocks) kommen. Als einfaches Beispiel seien zwei Prozesse

genannt, die beide zuerst eine Nachricht empfangen und erst anschließend selbst eine

Nachricht verschicken. Beide Prozesse würden in der MPI_RECV-Operation verhungern.

Die Operation MPI_Sendrecv(...) beugt diesem Problem vor, da sie Sende- und

Empfangsoperation gemeinsam abbildet. Da Verklemmungen aber ein generelles, nicht

MPI spezifisches Problem darstellen, werden sie im Rahmen dieser Ausarbeitung nicht

weiter behandelt. Näheres findet sich aber in [RR00, S195ff] oder auch in [QU03,

S.505ff].

Allerdings stehen auch nicht blockierende Operationen zur Verfügung,

MPI_Isend(...) und MPI_Irecv(...) genannt. Diese benachrichtigen Das

System, dass eine Nachricht im Sendepuffer zur Verfügung steht, bzw. der

Empfangspuffer auf eine Nachricht wartet. Während auf die Abholung/Ankunft der

Daten gewartet wird, können die Prozesse sich anderen Aufgaben widmen, der

jeweilige Puffer wird aber bis zur vollständigen Ausführung der Operation gesperrt. Zu

diesem Zweck erwarten die beiden Operationen grundsätzlich die selben Parameter wie

die blockierenden Äquivalente, erweitern die Parameterliste aber um MPI_Request

*request. Dieser Parameter bezeichnet eine Datenstruktur, die zur Identifikation und

Informationsgewinnung über den Status der Ausführung der Operation dient. Diese

Informationen werden vom System dort abgelegt. Ob die Ausführung beendet wurde

kann über die Methode

int MPI_Test( MPI_Request *request, int *flag, MPI_Status *status ),

abgerufen werden, wobei request die die betroffene Operation adressiert. Ist sie

beendet, erhält flag den Rückgabewerte 1, sonst 0. Der Parameter status hingegen

ist nur dann mit einem Rückgabewert belegt, wenn man eine bereit beendete

Empfangsoperation prüft und enthält dann von ihr beschriebene Informationen. In allen

anderen Fällen ist er undefiniert.

Page 15: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

15

Für sämtliche Operationen existieren drei verschiedene Übertragungsmodi. Im

Standardmodus wird über das System entschieden ob eine Zwischenspeicherung der

Nachrichten erfolgt. Um die Portabilität zu anderen Systemen sicherzustellen muss der

Programmierer die korrekte Funktionalität des Programms sicherstellen, sprich darauf

achten, dass es auch ohne Zwischenspeicherung richtig arbeitet.

Der synchrone Modus sorgt dafür, dass, wie der Name schon sagt, eine Synchronisation

zwischen Sender und Empfänger vorgenommen wird. im Rahmen der blockierenden

Operationen lassen sich dafür die Funktionen MPI_Ssend(...) und

MPI_Srecv(...) heranziehen, deren Parameter den bereits bekannten Methoden

entsprechen. Für die nicht blockierenden Operationen stehen MPI_Issend(...) und

MPI_Irecv(...) bereit. Diese benötigen allerdings zusätzliche Unterstützung der

Methode MPI_Wait(...) um die Synchronisierung zu gewährleisten, da sie ihrer Art

wegen normalerweise nicht warten.

Der Puffermodus besagt, dass nicht lokale Ereignisse keinen Einfluss auf die

Ausführung/Beendigung der lokalen Methoden haben dürfen. Die Nachrichten werden

im Bedarfsfall (Sendeoperation läuft, Empfangsoperation aber noch nicht) vom

Laufzeitsystem in Puffern zwischengespeichert. Diese müssen aber vom Programmierer

in ausreichender Größe zur Verfügung gestellt werden. Genutzt werden können die

blockierende Funktion MPI_Bsend(...) und die nicht blockierende

MPI_Ibsend(...). Als fortführende Lektüre sei auf [RR00, S.179ff] verwiesen.

3.4.3 Globale Kommunikations-Operationen

Neben den Einzeltransfer-Operationen gibt es auch solche, die Kommunikationen

zwischen allen oder zumindest mehreren Prozessen ermöglichen. Eine solche globale

Kommunikation kann verschiedene Zwecke erfüllen, welche im Folgenden anhand der

durch MPI zur Verfügung gestellten Funktionen vorgestellt werden. Im Gegensatz zu

den Punkt-zu-Punkt-Operationen muss hier jeder beteiligte Prozess dieselbe Funktion

mit ggf. für Sender und Empfänger unterschiedlichen Werten für die Parameter

aufrufen.

Sämtliche hier aufgeführten Operationen sind blockierend. Allerdings kann jeder

beteiligte Prozess sofort andere Programmteile ausführen, sobald seine Beteiligung an

der Operation abgeschlossen ist. Eine Synchronisation ist somit nicht unbedingt

gegeben, da es z.B. vorkommen kann, dass einige Prozesse bereits andere Operationen

Page 16: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

16

ausführen, während andere die entsprechende Kommunikationsoperation noch nicht

aufgerufen haben. Die Funktionen werden durch Abbildungen ergänzend beschrieben,

wobei pi jeweils den Prozess mit dem Index i beschreibt.

Bei der Broadcastoperation

int MPI_Bcast( void *message, int count, MPI_Datatype type, int root, MPI_Comm comm )

werden alle Prozesse von einem einzigen Prozess (im Folgenden als root oder

Wurzelprozess bezeichnet) mit denselben Daten beschickt. Jeder empfangende Prozess

muss denselben Prozess als root definieren und den gleichen Kommunikator comm

nutzen. message, count und type geben wie üblich den Nachrichtenpuffer, die -größe

und den -typ an. im Folgenden werden diese Parameter, sofern frei von Besonderheiten,

auch nicht mehr aufgeführt. Da die Broadcastoperation keinen Markierungs-Parameter

enthält ist wichtig zu wissen, dass, sollte der root mehrere Broadcast-Nachrichten

versenden, diese auch in derselben Reihenfolge von den betroffenen Prozessen

empfangen werden (auch wenn die Funktionen asynchron aufgerufen werden).

Abb. 3.4.3-1

Die Akkumulationsoperation

int MPI_Reduce( void *sendbuf, void *recvbuf, int count, MPI_Datatype type,

MPI_Op op, int root, MPI_Comm comm)

wird dann angewandt, wenn mehrere Prozesse Daten zur Verfügung stellen, die anhand

einer vordefinierten Reduktionsoperation bearbeitet werden (z.B. Maximum, Minimum

oder Summe). Hier stellen die beteiligten Prozesse dem root Nachrichten zur

Verfügung, für die eine bestimmte Reduktion op durchgeführt wird. Man ist nicht auf

die Verwendung der von MPI vordefinierten Reduktionsoperationen angewiesen, da

sich über die Funktion

int MPI_OP_create( MPI_User_function *function, int commute, MPI_OP *op )

Page 17: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

17

eigene Operationen konstruieren lassen. function verweist dabei auf eine vom

Programmierer zur Verfügung zu stellende Funktion, die vier Parameter void *a,

void *b, int *len und MPI_Datatype *type mitbringen muss. Es wird dann eine

Reduktion in der Form b[i] = a[i] op b[i] vorgenommen, wobei der Parameter

commute angibt, ob eine kommutative Operation vorliegt.

Abb. 3.4.3-2

Durch Anwendung der Gatheroperation

int MPI_Gather( void *sendbuf, void sendcount, MPI_Datatype sendtype, void *recvbuf, void recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm )

wird der Wurzelprozess root von allen anderen Prozessen mit Daten versorgt, ohne

dass eine Reduktionsoperation durchgeführt wird. Die Größe der insgesamt

empfangenen Nachricht ist beim root somit größer ist als die von den Prozessen

jeweils versandten. Jeder beteiligte Prozess muss denselben Prozess als root

adressieren und eine Nachricht in einer einheitlichen Größe versenden. Möchte man

letzteres vermeiden, kann auf die Vektorvariante MPI_Gatherv(...) zurückgegriffen

werden. Statt dem Parameter recvcount der die konkrete Nachrichtengröße angibt

werden hier zwei Parameter recvcounts und displs geführt, wobei der erste ein

Integerfeld adressiert, welches in i-ter Stelle die Nachrichtengröße für den Prozess i

angibt, der zweite hingegen festlegt an welcher Stelle im Empfangspuffer des

Wurzelprozesses die jeweilige Nachricht abgelegt wird. Hier liegt es im

Aufgabenbereich des Programmierers, sicherzustellen, dass Stellen im Empfangspuffer

nicht doppelt belegt sind, und Nachrichtengrößen bei Sender und Empfänger identisch

festgelegt sind.

Page 18: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

18

Abb. 3.4.3-3

Die Scatteroperation MPI_Scatter(...) entspricht in ihren Parametern der eben

besprochenen Gatheroperation. Grundlegend entspricht sie in ihrer Funktion einem

Broadcast, allerdings kann der Wurzelprozess hier unterschiedliche Daten (derselben

Größe) an jeden beteiligten Prozess senden. Hier gilt, dass, sollte man Nachrichten

unterschiedlicher Größe versenden wollen, man ebenfalls eine Vektorvariante

MPI_Scatterv(...) nutzen kann, welche dieselben Besonderheiten wie die zuvor im

Zuge der Gatheroperation vorgestellte aufweist.

Abb. 3.4.3-4

Die Multi-Broadcastoperation

int MPI_Allgather( void *sendbuf, void sendcount, MPI_Datatype sendtype, void *recvbuf, void recvcount, MPI_Datatype recvtype, MPI_Comm comm )

ist die erste Funktion, die ohne ausgezeichneten root auskommt. Alle beteiligten

Prozesse versorgen sich gegenseitig mit Daten (beispielsweise Teilergebnisse von

Berechnungen), hier werden somit keine Daten von zentraler Stelle verteilt, oder an

zentraler Stelle gesammelt. Auch hier gilt wieder: Erst durch eine Vektorvariante

MPI_Allscatterv(...) lassen sich Nachrichten mit unterschiedlicher Anzahl von

Elementen verschicken. Auch hier muss auf die zuvor erwähnten Besonderheiten

geachtet werden.

Page 19: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

19

Abb. 3.4.3-5

Der Zweck der Multi-Akkumulationsoperation

int MPI_Allreduce( void *sendbuf, void *recvbuf, int count, MPI_Datatype type, MPI_Op op, int root, MPI_Comm comm )

liegt lediglich darin, alle beteiligten Prozesse mit dem Ergebnis der durchgeführten

Akkumulation zu versorgen. Diese Operation ließe sich also auch durch ein

MPI_Reduce(...) gefolgt von einem MPI_Bcast(...) ersetzen.

Abb. 3.4.3-6

Von einem totalen Austausch

int MPI_Alltoall( void *sendbuf, void sendcount, MPI_Datatype sendtype, void *recvbuf, void recvcount, MPI_Datatype recvtype, MPI_Comm comm )

spricht man, wenn jeder Prozess mit jedem anderen interagiert, also (durchaus

unterschiedliche) Nachrichten austauscht. Auch diese Funktion braucht somit keinen

ausgezeichneten Wurzelprozess. Da diese Operation ebenfalls standardmäßig mit

Nachrichten indentischer Größe arbeitet, gibt es wieder eine Vektorvariante

MPI_Alltoallv(...). Auch hier gelten die bereits erwähnten speziellen

Eigenschaften.

Page 20: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

20

Abb. 3.4.3-7

Näheres zu allen, auch den hier nicht aufgeführten, Funktionen findet sich in [RR00, S.

182ff] oder in [QU03, S450, ff]. Zur Verdeutlichung ist ein die Broadcast- und

Akkumulationsoperation nutzendes Beispiel angehängt (Anhang A, QT02).

3.5 Zeitmessung (Benchmarking)

Die Zeitmessung eines MPI-Programms hebt sich nicht von der eines Programms im

Allgemeinen ab. Allerdings ist das so genannte Benchmarking gerade bei verteilter

Programmierung interessant um bestimmte Fragestellungen zu klären:

• Wie lange nimmt die Bearbeitung eines speziellen Problems in Anspruch?

• Welcher Zeitvorteil ergibt sich durch zusätzliche Hardware? Eine beispielhafte

Problematik wäre: Entspricht eine Verdopplung der Prozessorkapazität auch

einer Verdopplung der effektiven Bearbeitungsgeschwindigkeit?

• Identifizierung und Quantifizierung von brachliegenden Ressourcen, wenn

beispielsweise unterschiedlich schnelle Prozessoren genutzt werden und die

schnelleren Modelle ihre Teilaufgabe längst bearbeitet haben, während die

langsameren noch rechnen.

MPI bietet zu diesem Zweck eigene Funktionen an, die eine integrierte Zeitmessung

möglich machen. Der Ablauf einer solchen Zeitmessung kann wie folgt aussehen

(Ausschnitt):

start = MPI_Wtime(); ... zu messender Programmteil ... end = MPI_Wtime();

Die Differenz zwischen den beiden Werten (end-start) liefert die benötigte Zeit in

Sekunden. Über eine weitere Funktion MPI_Wtick() lässt sich außerdem bestimmen,

mit welcher Auflösung die Zeitmessung erfolgt ist, z.B. liefert sie auf einem System

dessen Zeitzähler jede Millisekunde inkrementiert eine 10-3 als Rückgabewert.

Page 21: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 3: MPI

21

3.6 Prozesstopologien

Bisher wurde eine Kommunikation mit einem Prozess stets über seinen innerhalb einer

Gruppe festgelegten Index abgewickelt. Spätestens dann, wenn man komplexere

Berechnungen in mehrdimensionalen Räumen vornehmen will, in dem jeder einem

Gitterpunkt zugeordnete Prozess mit seinen direkten Nachbarn im Gitter kommuniziert,

ist es sinnvoll andere Adressierungen einzuführen. MPI sieht hierfür so genannte

virtuelle Topologien vor. Diese lassen sich über die Funktion

int MPI_Cart_create( MPI_Comm comm, int ndims, int *dims, int *periods,

int reorder, MPI_Comm *ncomm)

anlegen. Basierend auf einem bestehenden Kommunikator comm wird ein Gitter mit

ndims Dimensionen angelegt. dims verweist auf ein Feld, dass für jede Dimension die

Anzahl der Prozesse definiert und über den korrespondierenden Eintrag des Feldes

periods wird festgelegt ob die Prozesse einer Dimension zyklisch verbunden werden

sollen. Ob die durch comm vorgegebene Reihenfolge übernommen, oder für den neuen

Kommunikator ncomm eine eventuell durch das Laufzeit für die Gitterdarstellung

optimierte Anordnung vorgenommen wird, bestimmt der Parameter reorder.

Bedingt durch die Komplexität einer solchen mehrdimensionalen Ausrichtung stellt

MPI eine weitere Funktion

int MPI_Dims_create( int nnodes, int ndims, int *dims)

zur Verfügung, welche das Verteilen der Prozesse auf die gewünschten Dimensionen

erleichtern soll. Hierbei wird über nnodes die Anzahl der Prozesse für das Gitter und

über ndims die Anzahl der Dimensionen vorgegeben. Das Feld dims entspricht dem

der zuvor besprochenen Funktion.

MPI stellt weitere Funktionen zur Verfügung, die das Umrechnen zwischen den

kartesischen Koordinaten der Gitterdarstellung und dem Prozess-Index ermöglichen,

bzw. umgekehrt. Darüber hinaus lassen sich die direkten Nachbarn im Gitter ermitteln

oder das Gitter in Teilgitter zerlegen. Dieses Kapitel aber bereits über die Grundlagen

von MPI hinausgeht, deshalb bleibt einer weitere Erläuterung dieser Funktionen aus.

Wichtig ist hier, dass MPI ein solches Konzept vorgibt und dieses durch verschiedenste

Funktionen bestückt.

Page 22: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Kapitel 4: Fazit

22

4 Fazit

Die vorangegangenen Kapitel haben wesentliche Grundlagen der parallelen

Programmierung mit MPI erläutert. Dabei wurden Parallel-Rechner zuerst definiert und

anschließend eine Klassifizierung vorgenommen in welche MPI dann eingeordnet

werden konnte.

Basierend auf Systemen mit verteiltem Speicher und dem daraus hervorgehenden

Zwang zum Nachrichtenaustausch erfolgte im Anschluss eine Einführung in das

Message Passing Programmiermodell. Darüber hinaus wurde anhand von OpenMP eine

Abgrenzung zu äquivalenten Spezifikationen für Systeme mit gemeinsamem Speicher

vorgenommen.

Um in die Möglichkeiten von MPI einzuführen, wurde die Thematik der

Kommunikation beginnend bei Prozessgruppen und Kommunikatoren über die

Einzeltransfer-Operationen bis hin zum globalen Nachrichtenaustausch eingehend

erläutert und anhand von Beispielen verdeutlicht.

Mit den darauf folgenden Kapiteln Zeitmessung (Benchmarking) und Prozesstopologien

wurden zwei Themenbereiche bearbeitet, die gerade im Zuge der MPI-Programmierung

von besonderem Interesse sind.

Im Rahmen der Seminararbeit ist es nicht möglich auf alle Einzelheiten des Themas

MPI einzugehen. Sie soll lediglich als Einstieg und Überblick dienen. Für eine

umfassendere Analyse des Themas sei auf die Quellen im Literaturverzeichnis

verwiesen.

Page 23: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

A Quelltexte

QT01 – Nachrichtenübertragung von Prozess 0 an Prozess 1

#include <stdio.h> #include <string.h> #include “mpi.h” int main (int argc, char *argv[]) { int my_rank, source, dest, tag=0; char msg [20]; MPI_Status status; // MPI Initialisieren MPI_Init (&argc, &argv); // Eigenen Rang bestimmen (wird in Kapitel 3.4.3 erläutert) MPI_Comm_rank ( MPI_COMM_WORLD, &my_rank); // Der Prozess mit Rang 0 sendet eine Nachricht... if (my_rank == 0) { strcpy (msg, “Testnachricht”); MPI_Send ( msg, strlen(msg)+1, MPI_Char, 1, tag, MPI_COMM_WORLD); } // ...und Prozess 1 empfängt sie if (my_rank == 1) { MPI_Recv ( msg, 20, MPI_Char, 0, tag, MPI_COMM_WORLD, &status); } // MPI beenden MPI_Finalize(); }

Page 24: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

QT02 – Broadcast & Akkumulation am Beispiel der parallelen Berechnung von PI

Die Funktion dient lediglich der Erläuterung der Funktionsweise. Wie genau die

Berechnung von PI hier erfolgt ist nicht von Belang und wird deshalb nicht eingehend

erläutert.

#include <stdio.h> #include <string.h> #include “mpi.h” int main(int argc, char *argv[]) { int rank, size; double x, pi, pi_part=0, start, stop, step; // MPI Initialisieren MPI_Init(&argc, &argv); // Eigenen Rang bestimmen MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); /* Prozess 0 liest eine für die Bestimmung von PI * notwendige Berechnung von Teilintegralen * vorgesehene Schrittweite ‘step’ ein */ if(rank==0) scanf("%lf", &step); // ‘step’ wird an die beteiligten Prozesse verteilt MPI_Bcast(&step, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); // Teilintegral berechnen start = (1.0*rank) / size; stop = start + 1.0/size; for(x=start; x<stop; x+=step) { pi_part += step * (4/(1+x*x)); } /* Mit Hilfe der Akkumulationsoperation MPI_SUM werden die * berechneten Teilintegrale aller Prozesse im Puffer pi * des Wurzelprozesses (Prozess 0) aufaddiert */ MPI_Reduce( &pi_part, &pi, 1, MPI_DOUBLE, MPI_SUM, 0,MPI_COMM_WORLD); // berechneten PI-Wert ausgeben if(rank==0) printf("pi=%.16f\n", pi); // MPI beenden MPI_Finalize(); }

Page 25: Message Passing Interface (MPI) - wi1.uni- · PDF fileWestfälische Wilhelms-Universität Münster Ausarbeitung Message Passing Interface (MPI) Im Rahmen des Seminars „Parallele

Literaturverzeichnis

[MP00] MPI-Website http://www.mpi-forum.org/

[RR00] Thomas Rauber, Gudula Rünger: Parallele und verteilte Programmierung, Springer-Lehrbuch, 2000

[QU03] M.J. Quinn: Parallel Programming in C with MPI and OpenMP, McGraw-Hill, 2003

[OP00] OpenMP-Website http://www.openmp.org

[CH00] MPI-CH-Website: http://www-unix.mcs.anl.gov/mpi/mpich/

[LA00] LAM-MPI-Website: http://www.lam-mpi.org/