Das Senden und Empfangen von Nachrichten ist der grundlegende
Mechanismus für die Kommunikation in MPI.
Jede Nachricht besitzt eine Art Briefumschlag, welcher
Sender und Empfänger werden durch ihren Rang (rank) im
Kommunikator identifiziert.
Der Kommunikator bezeichnet den Kontext, in welchem die
Kommunikation
stattfindet. Außerdem ist mit dem Kommunikator eine Gruppe von Prozessen
festgelegt. Innerhalb des Kommunikators können Nachrichten nur an die
Prozesse gesendet werden, die der Prozeßgruppe angehören. Ein vordefinierter
Kommunikator, welcher die Kommunikation zwischen allen Prozessen gestattet,
ist MPI_COMM_WORLD. Wenn die Problemstellung keine Arbeit mit speziellen
Kontexten erfordert, kann man immer, wenn ein comm-Argument verlangt
wird, MPI_COMM_WORLD verwenden.
Das message tag (tag) ist ein Integerwert und dient als eine Art
Stempel.
Es erlaubt die Unterscheidung von Nachrichten, und wird bei der
Empfangsoperation abgefragt. Das tag kann Werte von 0 bis UB annehmen,
wobei der höchste Wert für Tags in MPI_TAG_UB definiert ist.
Sender und Empfänger werden durch ihren Rang im Kommunikator
bezeichnet. Der Rang ist innerhalb eines Kommunikators eindeutig und
identifiziert einen Prozeß.
Zudem wird bei jedem Kommunikationsvorgang der Datentyp der Nachricht angegeben. Das kann einer der in MPI definierten Basisdatentypen oder ein abgeleiteter Datentyp sein. Mit dem Mechanismus der Datentypen wird dem Nutzer die Sorge um Byteordering und Datenkonvertierung in heterogenen Systemen wie z.B. Workstation-Clustern abgenommen. MPI sorgt selbst für die Umwandlung in die Netzdarstellung und die Rückkonvertierung in den Datentyp, als Parameter in der Empfangsoperation angegeben wurde.
Die Kommunikation läuft in drei Phasen ab:
Für jede Sende- und Empfangsoperation gibt es eine blockierende und eine
nichtblockierende Variante. Eine blockierende Operation kehrt erst zurück,
wenn die Nachricht je nach Modus dem Empfänger übermittelt oder in einem
Puffer zwischengespeichert wurde. Das bedeutet, daß der Nutzer wieder frei
über den Puffer verfügen kann.
Die nichtblockierenden Funktionen kehren sofort zurück und liefern ein
Request-handle. Mit Hilfe dieses handles und weiterer Testfunktionen kann
man prüfen, ob die Operation beendet ist. Erst dann darf über den Puffer
verfügt werden.
MPI gibt dem Programmierer die Möglichkeit, das Kommunikationsprotokoll selbst zu bestimmen. Deshalb gibt es für die blockierende wie für die nichtblockierende Variante vier Kommunikationsmodi. Über den Modus entscheidet der Sender allein.
Kommunikationsmodi:
Gepufferter Modus: Der Nutzer muß vor dem Senden selbst einen Puffer bereitstellen, in dem die Daten gespeichert werden, bis die Empfangsoperation sie benötigt. Die Sendeoperation wird beendet, unabhängig davon, ob eine passende Empfangsoperation gestartet wurden. Damit wird im Prinzip das Senden vom Empfangen unabhängig gemacht.
Synchroner Modus: Das Senden kann beginnen, egal ob eine Empfangsoperation gestartet wurde. Die Operation wird jedoch nicht beendet, bevor die passende Empfangsoperation begonnen hat, Daten in den Empfangspuffer zu kopieren. Wenn Sender und Empfänger blockierende Operationen verwenden, hat dieser Modus einen synchronisierenden Effekt.
Ready-Modus: Eine Sendeoperation darf nur gestartet werden, wenn
bereits eine passende Empfangsoperation gestartet wurde. Auf einigen
Rechnern erlaubt dies, auf das handshake-Verfahren, wie es beim synchronen
Senden üblich ist, zu verzichten und die Performance zu verbessern.
Die meisten MPI-Implementationen setzen derzeit den Ready-Modus mit dem
Standardmodus gleich, so daß ein Performancegewinn mit dieser Variante
nicht möglich ist.
Die Thematik der Punkt-zu-Punkt Kommunikation ist recht umfangreich und soll deshalb in einige Teilbereiche gegliedert werden: