next up previous
Next: Die Auto-Parallelisierungs Option (APO) Up: Werkzeuge zum Erstellen paralleler Previous: POSIX Threads

Message Passing Interface - MPI

MPI ist der Standard für das Erstellen von nachrichtenbasierten parallelen Programmen. MPI ist eine Programmbibliothek, die die Funktionalität zur Synchronisation und für den Datenaustausch zwischen den einzelnen parallelen Prozessen zur Verfügung stellt.

Im Prinzip wird die gesammte Kommunikation über nur zwei Befehle bewerkstelligt:

MPI_Send verschickt eine Botschaft an einen anderen Prozess.

MPI_Recv versucht einen Botschaft zu empfangen.

Ein kurzes MPI-Programm könnte in etwa so aussehen:

/* beispielprogramm               */

/* parallele matrixmultiplikation mit mpi */

#include <stdio.h>
#include "mpi.h"

#define SIZE	4

int main(int argc, char **argv) {

  int            myrank, mysize;
  MPI_Status     stat;

  int i, j;
  float matrix1[SIZE][SIZE], matrix2[SIZE][SIZE], result[SIZE][SIZE];

  /* initialisierungen */
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  MPI_Comm_size(MPI_COMM_WORLD, &mysize);

  if (mysize != SIZE) {
    fprintf(stderr, "error: num of processes does not match matrix-size\n");
    exit(1);
  }

  /* prozess 0 erzeugt 2 matrizen, die multipliziert werden sollen */
  if (myrank == 0) {
    for (i=0; i<SIZE; i++)
      for (j=0; j<SIZE; j++) {
        matrix1[i][j] = 1; 
        matrix2[i][j] = 1;
        result[i][j] = 0;
      }
    printf("matrix1:\n");
    for (i=0; i<SIZE; i++) {
      for (j=0; j<SIZE; j++) 
        printf("%f ", matrix1[i][j]);
printf("\n");
    }
    printf("matrix2:\n");
    for (i=0; i<SIZE; i++) {
      for (j=0; j<SIZE; j++) 
        printf("%f ", matrix2[i][j]);
printf("\n");
    }

    /* matrizen werden auf die uebrigen prozesse aufgeteilt   */
    for (i=1; i<mysize; i++) {
      MPI_Send(matrix1, SIZE*SIZE, MPI_FLOAT, i, 47, MPI_COMM_WORLD);
      MPI_Send(matrix2, SIZE*SIZE, MPI_FLOAT, i, 11, MPI_COMM_WORLD);
    }
  } else {
    /* die uebrigen prozesse muessen die daten empfangen */

    MPI_Recv(matrix1, SIZE*SIZE, MPI_FLOAT, 0, 47, MPI_COMM_WORLD, &stat);
    MPI_Recv(matrix2, SIZE*SIZE, MPI_FLOAT, 0, 11, MPI_COMM_WORLD, &stat);
  }

  /* jeder prozess besitzt jetzt beide matrizen */

  /* berechnung */ 
  for (i=0; i<SIZE; i++) {
    for (j=0; j<SIZE; j++) {
      result[myrank][i] += matrix1[myrank][j] * matrix2[j][i];
    }
  }

  if (myrank == 0) {
    for (i=1; i<mysize; i++) 
      MPI_Recv(result[i*SIZE], SIZE, MPI_FLOAT, i, 13, MPI_COMM_WORLD, &stat);

    printf("result: \n");
    for (i=0; i<SIZE; i++) {
      for (j=0; j<SIZE; j++) 
        printf("%f ", result[i][j]);
printf("\n");
    }
  } else
    MPI_Send(result[myrank*SIZE], SIZE, MPI_FLOAT, 0, 13, MPI_COMM_WORLD);

  MPI_Finalize();

  return(0);

}




Mail to: Oliver Schönbrunner