MPI (Message Passing Interface, siehe MPI im Glossar) ist der Standard für verteilte Systeme und Supercomputer: Viele Prozesse mit getrenntem Speicher tauschen Nachrichten. Die wichtigsten Implementierungen sind Open MPI, MPICH und Intel MPI; gestartet wird ein Programm mit mpirun -np 4 ./programm.

Initialisierung und Umgebung

MPI_Init(&argc, &argv);        // MPI starten
MPI_Comm_rank(MPI_COMM_WORLD, &rank);  // eigene Prozess-Nummer
MPI_Comm_size(MPI_COMM_WORLD, &size);  // Anzahl Prozesse
MPI_Get_processor_name(name, &len);
MPI_Finalize();                // MPI beenden

MPI_COMM_WORLD ist der Standard-Kommunikator; rank (0 bis size-1) identifiziert jeden Prozess.

Punkt-zu-Punkt-Kommunikation

MPI_Send(buf, count, MPI_INT, dest, tag, MPI_COMM_WORLD);
MPI_Recv(buf, count, MPI_INT, src, tag, MPI_COMM_WORLD, &status);
MPI_Isend(buf, count, MPI_INT, dest, tag, MPI_COMM_WORLD, &req);  // nichtblockierend
MPI_Irecv(buf, count, MPI_INT, src, tag, MPI_COMM_WORLD, &req);
MPI_Wait(&req, &status);

Nichtblockierende Varianten (MPI_Isend/MPI_Irecv) überlappen Kommunikation und Rechnen; MPI_Wait wartet auf den Abschluss, MPI_Test prüft nur.

Kollektive Operationen

MPI_Bcast(buf, count, MPI_INT, root, MPI_COMM_WORLD);   // an alle senden
MPI_Reduce(&local, &result, 1, MPI_DOUBLE, MPI_SUM, root, MPI_COMM_WORLD);
MPI_Allreduce(&local, &result, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
MPI_Scatter(sendbuf, n, MPI_INT, recvbuf, n, MPI_INT, root, MPI_COMM_WORLD);
MPI_Gather(recvbuf, n, MPI_INT, sendbuf, n, MPI_INT, root, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);

MPI_Bcast verteilt ein Datum von einem Prozess an alle, MPI_Reduce sammelt Teilergebnisse (etwa mit MPI_SUM oder MPI_MAX) bei einem Prozess, MPI_Allreduce bei allen. MPI_Scatter/MPI_Gather teilen bzw. sammeln Arrays.

Verwandte Grundlagen: OpenCL-Befehle, OpenMP-Befehle, Verteilte Systeme, Supercomputer, GPU.