From 69f6e369bacae5c485f93dd44770321c4e0357a3 Mon Sep 17 00:00:00 2001 From: Marco Ammon Date: Fri, 13 Sep 2019 18:20:28 +0200 Subject: [PATCH] MPI: bis kollektive Operationen begonnen --- 2-3-mpi.tex | 114 +++++++++++++++++++++++++++++++++++++++++++- zusammenfassung.tex | 11 ++++- 2 files changed, 123 insertions(+), 2 deletions(-) diff --git a/2-3-mpi.tex b/2-3-mpi.tex index 90f78bf..5f663a5 100644 --- a/2-3-mpi.tex +++ b/2-3-mpi.tex @@ -1 +1,113 @@ -\subsection{Message Passing Interface (MPI)} \ No newline at end of file +\subsection{Message Passing Interface (\textsc{MPI})} +\subsubsection{Allgemeines} +\begin{itemize} + \item Message-Passing--Programme: \begin{itemize} + \item in sequentieller Sprache geschrieben + \item Variablen sind prozesslokal + \item Start auf vielen Prozessoren/Knoten + \item unterschiedliches Verhalten abhängig von der Prozessnummer + \item Kommunikation durch explizite, zweiseitige Bibliotheksaufrufe (etwa MPI) + \end{itemize} + \item MPI ist ein Standard für C und Fortran, der Funktionssignaturen und Semantik festlegt + \item verschiedene Implementierungen wie \textsc{OpenMPI} oder \textsc{Intel MPI} +\end{itemize} + +\subsubsection{Operationen} +\begin{itemize} + \item Eigenschaften einer Nachricht: \begin{itemize} + \item Senderkennung + \item Adresse der Quelldaten + \item Datentyp (primitiv, zusammengesetzt, etc.) + \item Anzahl der Datenelement jeweils bei Sender und Empfänger + \item Empfängerkennung (einer oder mehrere) + \item Adresse der Zieldaten + \end{itemize} + \item blockierend: alle Puffer der Operation können direkt nach Rückkehr des Aufrufs wiederverwendet werden + \item nicht-blockierend: Puffer erst nach Abschluss der Operation wieder verwendbar + \item lokal: kehrt immer zurück, unabhängig von Aktionen anderer Prozesse + \item nicht-lokal: kehrt erst zurück, wenn in anderem Prozess bestimmte Bedingung auftritt + \item \lstinline|MPI_Init()|: Initialisieren der MPI-Strukturen + \item \lstinline|MPI_Finalize()|: Abschluss aller MPI-bezogenen Operationen und Freigabe der MPI-Strukturen + \item \lstinline|MPI_Comm_rank(MPI_Comm comm, int *rank)|: Bestimmung des Rangs im übergebenen Kommunikator + \item \lstinline|MPI_Comm_size(MPI_Comm comm, int *size)|: Bestimmung des Größe des übergebenen Kommunikators + \item \lstinline|MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)|: Senden einer Nachricht (Verhalten implementierungsabhängig) + \item \lstinline|MPI_Ssend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)|: synchrones Senden (nicht-lokal, blockierend), kehrt nach Empfangsaufruf in anderem Prozess zurück \begin{itemize} + \item Übertragung größerer Datenmengen unterschiedlicher Größen + \end{itemize} + \item \lstinline|MPI_Bsend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)|: gepuffertes Senden (lokal, blockierend), kehrt nach Kopieren der Nachricht zurück: \begin{itemize} + \item Vermeidung von Blockierungsgefahr + \item Überlappung von Berechnungen mit Kommunikation (aber dafür öfter Kopieren!) + \item Bereitstellung ausreichend großer Puffer am Programmanfang notwendig mittels \lstinline|MPI_Buffer_attach(void *buffer, size_t size)| und \lstinline|MPI_Pack_size(int count, MPI_Datatype type, MPI_Communicator comm, int *size)| + \end{itemize} + \item \lstinline|MPI_Rsend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)|: sofortiges Senden, erwartet dass Empfangsauftrag bereits abgesetzt wurde: \begin{itemize} + \item Versenden vieler kleiner Nachrichten + \item Überlappung Kommunikation mit Berechnung nicht gewünscht + \item garantierter Empfangsauftrag notwendig (z.B. am Anfang mit \texttt{MPI\_Irecv} bereitstellen) + \end{itemize} + \item \lstinline|MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status status)|: Empfang + \item \lstinline|MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status status)|:\\ + gleichzeitiges Senden und Empfangen + \item gleichbleibende Operationen (Typ, Größe, Tag, Empfänger, Puffer, \textellipsis): \begin{itemize} + \item \lstinline|MPI_Send_Init(void *buf, int count, MPI_Datatype type, int dest, int tag, MPI_Comm comm, MPI_Request *request)|: Anlegen des Sendeauftrags + \item \lstinline|MPI_Start(MPI_Request *request)|: Starten des Sendeauftrags + \item \lstinline|MPI_Request_free(MPI_Request *request)|: Freigeben des Sendeauftrags + \end{itemize} angelegt und durch + \item nicht-blockierende Varianten \lstinline|MPI_I...| (lokal) geben \lstinline|MPI_Request| zurück \begin{itemize} + \item Überlagerung von Berechnungen mit Kommunikation möglich + \item gleichzeitiges Empfangen von verschiedenen Nachrichten möglich + \end{itemize} + \item \lstinline|MPI_Wait(MPI_Request *request, int *flag, MPI_Status *status)|: blockierendes Warten auf Ende des übergebenen Requests + \item \lstinline|MPI_Test(MPI_Request *request, int *flag, MPI_Status *status)|: Testen auf Ende des übergebenen Requests + \item \lstinline|MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status)|: blockierender Empfangstest + \item \lstinline|MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count)|: Länge der zu empfangenen Nachricht (kann zur Allokation von Puffern genutzt werden) +\end{itemize} + +\subsubsection{Kollektive Operationen} +\begin{itemize} + \item müssen von allen Prozessen des Kommunikators in der gleichen Reihenfolge aufgerufen werden + \item Synchronisation durch \lstinline|MPI_Barrier(MPI_Comm comm)|: Fortsetzung erst dann, wenn alle Prozesse Aufruf getätigt haben + \item Kommunikation: \begin{itemize} + \item \lstinline|MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)|: Versenden bzw. Empfangen einer Nachricht von einem Knoten an alle anderen + \item \lstinline|MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)|: elementweises Verteilen eines Arrays an alle Prozesse des Kommunikators + \item \lstinline|MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)|: Aufsammeln von Datenelementen von allen Prozessen und Speicherung als Array in einem Prozess + \item \lstinline|MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)|: Aufsammeln von Datenelementen von allen Prozessen und Speicherung als Array in jedem Prozess + \end{itemize} + \item Reduktion: \begin{itemize} + \item + \end{itemize} +\end{itemize} + +\subsubsection{Kommunikatoren} +\begin{itemize} + \item bestehen aus \begriff{Prozessgruppe} und \begriff{Nachrichtenkontext} + \item erlauben die Kommunikation von Bibliotheken, ohne die des eigentlichen Programms zu beeinflussen + \item \lstinline|MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm)|: Erzeugung eines neuen Kommunikators aus einer Gruppe + \item \lstinline|MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)|: Erzeugung neuer Kommunikatoren durch Gruppierung nach \texttt{color}, Rangbestimmung durch Sortieren von \texttt{key} + \item Mengenoperationen auf Gruppen + \item virtuelle Topologien: Abbildung von Prozessnummern auf einen Namensraum: \begin{itemize} + \item Teil des Nachrichtenkontexts + \item Graph:\begin{itemize} + \item \lstinline|MPI_Graph_create(MPI_Comm comm, int nnodes, int index[], int edges[], int reorder, MPI_Comm *newcomm)|: Erstellung neues Kommunikators aus Kanten (\texttt{index} gibt pro Knoten die erste Kante in \texttt{edges} an) + \item \lstinline|MPI_Graph_neighbors_count(MPI_Comm comm, int rank, int *count)|: Bestimmung der Anzahl der Nachbarn von \texttt{rank} + \item \lstinline|MPI_Graph_neighbors(MPI_Comm comm, int rank, int maxneighbors, int *neighbors)|: Bestimme Ränge der Nachbarn von \texttt{rank} + \end{itemize} + \item kartesische Koordinaten:\begin{itemize} + \item \lstinline|MPI_Cart_create(MPI_Comm comm, int ndims, int dims[], int periods[], int reorder, MPI_Comm *newcomm)|: Erzeugung eines \texttt{ndims}-dimensionalen Gitters + \item \lstinline|MPI_Cart_coords(MPI_Comm comm, int rank, int ndims, int coords[])|: Abbildung von Rang auf Koordinaten + \item \lstinline|MPI_Cart_rank(MPI_Comm comm, int coords[], int *rank)|: Abbildung von Koordinaten auf Rang + \item \lstinline|MPI_Cart_shift(MPI_Comm comm, int direction, int disp, int *rank_src, int *rank_dest)|: Ermittlung der Ränge benachbarter Knoten im Gitter + \end{itemize} + \end{itemize} +\end{itemize} + +\subsubsection{Datentypen} +\begin{itemize} + \item primitive Datentypen für Ganz- und Fließkommazahlen + \item abgeleitete Datentypen:\begin{itemize} + \item allgemein: $((\mathrm{type}_0, \mathrm{disp}_0), \dots, (\mathrm{type}_{n-1}, \mathrm{disp}_{n-1}))$ + \item \texttt{struct}: \lstinline|MPI_Type_struct(int count, int blocklengths[], MPI_Aint displacements[], MPI_Datatype types[], MPI_Datatype *newtype)| + \item zusammenhängender Speicher: \lstinline|MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype)| + \item Vektor: \lstinline|MPI_Type_vector(int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype)| + \item \lstinline|MPI_Type_commit(MPI_Datatype *type)|: Festlegen des Datentyps + \end{itemize} +\end{itemize} \ No newline at end of file diff --git a/zusammenfassung.tex b/zusammenfassung.tex index b3c4625..65e9897 100644 --- a/zusammenfassung.tex +++ b/zusammenfassung.tex @@ -1,6 +1,6 @@ \documentclass[11pt,a4paper]{scrartcl} \usepackage[table]{xcolor} -\usepackage[a4paper,left=1.5cm,right=1.5cm,top=2.0cm,bottom=2.0cm]{geometry} +\usepackage[a4paper,left=1.5cm,right=1.5cm,top=2.5cm,bottom=2.5cm]{geometry} \usepackage[ngerman]{babel} \usepackage{amssymb} \usepackage{mathrsfs} @@ -37,6 +37,15 @@ \tikzset{rectangle state/.style={draw,rectangle}} +\lstset{ + frame=tb, + language=C, + basicstyle={\small\ttfamily}, + keywordstyle=\color{fau_blau}\bfseries, + breaklines=true, + breakatwhitespace=true, + tabsize=4} + \title{Zusammenfassung \enquote{Programmierung \& Architekturen von Cluster-Rechnern}} \author{Marco Ammon} \date{\today}