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.