mirror of
https://github.com/MartinThoma/LaTeX-examples.git
synced 2025-04-25 06:18:05 +02:00
185 lines
No EOL
8.5 KiB
TeX
185 lines
No EOL
8.5 KiB
TeX
%!TEX root = Programmierparadigmen.tex
|
|
\chapter{MPI}
|
|
\index{MPI|(}
|
|
|
|
Message Passing Interface (kurz: MPI) ist ein Standard,
|
|
der den Nachrichtenaustausch bei parallelen Berechnungen auf
|
|
verteilten Computersystemen beschreibt.
|
|
|
|
Prozesse kommunizieren in MPI über sog. \textit{Kommunikatoren}. Ein Kommunikator
|
|
(\texttt{MPI\_Comm}\xindex{MPI\_Comm})
|
|
definiert eine Menge an Prozessen, die miteinander kommunizieren können. In dieser
|
|
Prozessgruppe hat jeder Prozess einen eindeutigen \textit{rank}\xindex{rank} über den die Prozesse
|
|
sich identifizieren können.
|
|
|
|
\section{Erste Schritte}
|
|
\inputminted[numbersep=5pt, tabsize=4, frame=lines, label=hello-world.c]{c}{scripts/mpi/hello-world.c}
|
|
|
|
Das wird \texttt{mpicc hello-world.c} kompiliert.\\
|
|
Mit \texttt{mpirun -np 14 scripts/mpi/a.out} werden 14 Kopien des Programms
|
|
gestartet.
|
|
|
|
Hierbei ist \texttt{MPI\_COMM\_WORLD}\xindex{MPI\_COMM\_WORLD} der Standard-Kommunikator,
|
|
der von \texttt{MPI\_Init} erstellt wird.
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\section{MPI Datatypes}\xindex{MPI datatypes}
|
|
|
|
\begin{table}[h]
|
|
\begin{tabular}{|l|l||p{3.2cm}|l|}
|
|
\hline
|
|
MPI datatype & C datatype & MPI datatype & C datatype \\ \hline
|
|
MPI\_INT & signed int & MPI\_FLOAT & float \\
|
|
MPI\_UNSIGNED & unsigned int & MPI\_DOUBLE & double \\
|
|
MPI\_CHAR & signed char & MPI\_UNSIGNED\newline{}\_CHAR & unsigned char \\ \hline
|
|
\end{tabular}
|
|
\end{table}
|
|
|
|
\section{Funktionen}
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-size.c}\xindex{MPI\_Comm\_size}%
|
|
Liefert die Größe des angegebenen Kommunikators; dh. die Anzahl der Prozesse in der Gruppe.
|
|
|
|
\textbf{Parameter}
|
|
\begin{itemize}
|
|
\item \textbf{comm}: Kommunikator (handle)
|
|
\item \textbf{size}: Anzahl der Prozesse in der Gruppe von \texttt{comm}
|
|
\end{itemize}
|
|
|
|
\textbf{Beispiel}
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-size-example.c}
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\goodbreak
|
|
\rule{\textwidth}{0.4pt}\xindex{MPI\_Comm\_rank}%
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-rank.c}
|
|
Bestimmt den Rang des rufenden Prozesses innerhalb des Kommunikators.
|
|
|
|
Der Rang wird von MPI zum Identifizieren eines Prozesses verwendet. Die Rangnummer ist innerhalb eines Kommunikators eindeutig. Dabei wird stets von Null beginnend durchnumeriert. Sender und Empfänger bei Sendeoperationen oder die Wurzel bei kollektiven Operationen werden immer mittels Rang angegeben.
|
|
|
|
\textbf{Parameter}
|
|
\begin{itemize}
|
|
\item \textbf{comm}: Kommunikator (handle)
|
|
\item \textbf{rank}: Rang des rufenden Prozesses innerhalb von \texttt{comm}
|
|
\end{itemize}
|
|
|
|
\textbf{Beispiel}
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/comm-rank-example.c}
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\goodbreak
|
|
\rule{\textwidth}{0.4pt}\xindex{MPI\_Send}%
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-send.c}
|
|
Senden einer Nachricht an einen anderen Prozeß innerhalb eines Kommunikators. (Standard-Send)
|
|
|
|
\textbf{Parameter}
|
|
\begin{itemize}
|
|
\item \textbf{buf}: Anfangsadresse des Sendepuffers
|
|
\item \textbf{count}: Anzahl der Elemente des Sendepuffers (nichtnegativ)
|
|
\item \textbf{datatype}: Typ der Elemente des Sendepuffers (handle)
|
|
\item \textbf{dest}: Rang des Empfängerprozesses in comm (integer)
|
|
\item \textbf{tag}: message tag zur Unterscheidung verschiedener Nachrichten;
|
|
Ein Kommunikationsvorgang wird durch ein Tripel (Sender, Empfänger, tag) eindeutig beschrieben.
|
|
\item \textbf{comm}: Kommunikator (handle)
|
|
\end{itemize}
|
|
|
|
\textbf{Beispiel}
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-send-example.c}
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\goodbreak
|
|
\rule{\textwidth}{0.4pt}\xindex{MPI\_Recv}%
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-receive.c}
|
|
Empfangen einer Nachricht (blockierend)
|
|
|
|
\textbf{Parameter}
|
|
\begin{itemize}
|
|
\item \textbf{buf}: Anfangsadresse des Empfangspuffers
|
|
\item \textbf{count}: Anzahl (d.~h. $\geq 0$) der Elemente im Empfangspuffer
|
|
\item \textbf{datatype}: Typ der zu empfangenden Elemente (handle)
|
|
\item \textbf{source}: Rang des Senderprozesses in comm oder \texttt{MPI\_ANY\_SOURCE}
|
|
\item \textbf{tag}: message tag zur Unterscheidung verschiedener Nachrichten
|
|
Ein Kommunikationsvorgang wird durch ein Tripel (Sender, Empfänger, tag) eindeutig beschrieben. Um Nachrichten mit beliebigen tags zu empfangen, benutzt man die Konstante \texttt{MPI\_ANY\_TAG}.
|
|
\item \textbf{comm}: Kommunikator (handle)
|
|
\item \textbf{status}: Status, welcher source und tag angibt (\texttt{MPI\_Status}).
|
|
Soll dieser Status ignoriert werden, kann \texttt{MPI\_STATUS\_IGNORE}\xindex{MPI\_STATUS\_IGNORE} angegeben werden.
|
|
\end{itemize}
|
|
|
|
\textbf{Beispiel}
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-receive-example.c}
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\goodbreak
|
|
\rule{\textwidth}{0.4pt}\xindex{MPI\_Reduce}%
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-reduce.c}
|
|
Führt eine globale Operation \textbf{op} aus; der Prozeß \enquote{root} erhält das Resultat.
|
|
|
|
\textbf{Parameter}
|
|
\begin{itemize}
|
|
\item \textbf{sendbuf}: Startadresse des Sendepuffers
|
|
\item \textbf{count}: Anzahl der Elemente im Sendepuffer
|
|
\item \textbf{datatype}: Datentyp der Elemente von \texttt{sendbuf}
|
|
\item \textbf{op}: auszuführende Operation (handle)
|
|
\item \textbf{root}: Rang des Root-Prozesses in comm, der das Ergebnis haben soll
|
|
\item \textbf{comm}: Kommunikator (handle)
|
|
\end{itemize}
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\goodbreak
|
|
\rule{\textwidth}{0.4pt}\xindex{MPI\_Alltoall}%
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-alltoall.c}
|
|
Teilt Daten von jedem Prozeß einer Gruppe an alle anderen auf.
|
|
|
|
\textbf{Parameter}
|
|
\begin{itemize}
|
|
\item \textbf{sendbuf}: Startadresse des Sendepuffers
|
|
\item \textbf{sendcount}: Anzahl der Elemente im Sendepuffer
|
|
\item \textbf{sendtype}: Datentyp der Elemente des Sendepuffers (handle)
|
|
\item \textbf{recvcount}: Anzahl der Elemente, die von jedem einzelnen Prozeß empfangen werden
|
|
\item \textbf{recvtype}: Datentyp der Elemente im Empfangspuffer (handle)
|
|
\item \textbf{comm}: Kommunikator (handle)
|
|
\end{itemize}
|
|
|
|
\textbf{Beispiel}
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-alltoall-example.c}
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\goodbreak
|
|
\rule{\textwidth}{0.4pt}\xindex{MPI\_Bcast}%
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-bcast.c}
|
|
Sendet eine Nachricht vom Prozess \texttt{root} an alle anderen Prozesse des
|
|
angegebenen Kommunikators.
|
|
|
|
\textbf{Parameter}
|
|
\begin{itemize}
|
|
\item \textbf{buffer}: Startadresse des Datenpuffers
|
|
\item \textbf{count}: Anzahl der Elemente im Puffer
|
|
\item \textbf{datatype}: Datentyp der Pufferelemente (handle)
|
|
\item \textbf{root}: Wurzelprozeß; der, welcher sendet
|
|
\item \textbf{comm}: Kommunikator (handle)
|
|
\end{itemize}
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
\goodbreak
|
|
\rule{\textwidth}{0.4pt}\xindex{MPI\_Scatter}%
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-scatter.c}
|
|
Verteilt Daten vom Prozess \texttt{root} unter alle anderen Prozesse in der Gruppe, so daß, soweit möglich, alle Prozesse gleich große Anteile erhalten.
|
|
|
|
\textbf{Parameter}
|
|
\begin{itemize}
|
|
\item \textbf{sendbuf}: Anfangsadresse des Sendepuffers (Wert ist lediglich für 'root' signifikant)
|
|
\item \textbf{sendcount}: Anzahl der Elemente, die jeder Prozeß geschickt bekommen soll (integer)
|
|
\item \textbf{sendtype}: Datentyp der Elemente in sendbuf (handle)
|
|
\item \textbf{recvcount}: Anzahl der Elemente im Empfangspuffer. Meist ist es günstig, recvcount = sendcount zu wählen.
|
|
\item \textbf{recvtype}: Datentyp der Elemente des Empfangspuffers (handle)
|
|
\item \textbf{root}: Rang des Prozesses in comm, der die Daten versendet
|
|
\item \textbf{comm}: Kommunikator (handle)
|
|
\end{itemize}
|
|
|
|
\textbf{Beispiel}
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-reduce-example.c}
|
|
|
|
\section{Beispiele}
|
|
|
|
\inputminted[numbersep=5pt, tabsize=4]{c}{scripts/mpi/mpi-sum-reduce.c}
|
|
|
|
\section{Weitere Informationen}
|
|
\begin{itemize}
|
|
\item \url{http://mpitutorial.com/}
|
|
\item \url{http://www.open-mpi.org/}
|
|
\item \url{http://www.tu-chemnitz.de/informatik/RA/projects/mpihelp/}
|
|
\end{itemize}
|
|
|
|
\index{MPI|)} |