\documentclass[10pt,a4paper]{article}
\usepackage[dutch]{babel}
\usepackage[utf8]{inputenc}
\usepackage{booktabs,graphicx,float,hyperref}

% Paragraph indentation
\setlength{\parindent}{0pt}
\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex}

\title{Modelleren, Simuleren \& Contin\"ue Wiskunde \\
       Opdracht 4: Parallel programming \\
       Deel 1: Ringcommunicatie}
\author{Tadde\"us Kroes (6054129)}

\begin{document}

\maketitle
\tableofcontents
\pagebreak

\section{Inleiding}

In dit deel van practicum 4 worden de latency en throughput van MPI
communicatie in het gebruikte netwerk (het UvA netwerk) bepaald. Hiervoor wordt
gebruik gemaakt van een programma dat ringcommunicatie implementeert.

\section{Theorie}

Om de latency en throughput van de communicatie te bepalen moeten tijdmetingen
gedaan worden voor verschillende hoeveelheden van te verzenden data. De
throughput van de communicatie zou constant moeten zijn, dus zou de hoogte van
de tijdmetingen lineair moeten toenemen met de pakketgrootte. De verwachtig is
dus dat er een lineair verband is tussen de tijdmetingen en de bijbehorende
pakketgroottes, waarvan de parameters kunnen worden bepaald met een lineaire
Least Squares fit\footnote{\url{http://en.wikipedia.org/wiki/Least\_squares}}.
De latency en throughput zijn dan gelijk aan de uitkomst van de Least Squares
berekening (namelijk de waarde op $pakketgrootte = 0$ en de
richtingscoëfficiënt van het verband respectievelijk).

De metingen worden gedaan in een ringcommunicatie. Omdat de latencies erg laag
zijn, vooral bij kleine pakketgroottes, is het goed om gebruik te maken van een
ringstructuur omdat dit de totale tijd van de meting vergroot. Er is een
beperking op de nauwkeurigheid waarmee kan worden gemeten (te achterhalen met
de functie MPI\_Wtick, in ons geval $0.000001s = 1 \mu s$). Aangezien het
uiteindelijke resultaat wordt gedeeld door het aantal processen in de ring,
is de meetnauwkeurigheid gelijk aan $\frac{1}{aantal} \mu s$.

Aangezien de latency in dit
geval alleen de communicatie zelf betreft (dus de tijd die het pakket
daadwerkelijk onderweg is over het netwerk) wordt de verwerkingstijd op elke
``node'' in de ring verwaarloosd. Om toch een zo betrouwbaar mogelijk resultaat te
behalen wordt elke meting meerdere keren uitgevoerd en wordt alleen de minimale
waarde gebruikt, zodat de verwerkingstijden zoveel mogelijk worden
weggecijferd.

\section{Implementatie}

De metingen worden gedaan in een enkel proces: het ``master''-proces. De master
stuurt data naar het eerste ``slave''-proces die het vervolgens naar de
volgende slave doorstuurt, enzovoorts. De laatste slave stuurt de data naar de
master, die vervolgens de tijd meet die het pakket erover gedaan heeft om terug
te komen. Deze ciclus herhaalt zich voor een aantal verschillende
pakketgroottes. De parameters voor de metingen kunnen worden ingesteld in
enkele constantes bovinin het bestand \emph{ring.c}:
\begin{verbatim}
#define LOOP 100        // Number of different message sizes
#define STRIDE 10000    // Difference between the message sizes
#define REPEAT 7        // Number of times to repeat a measurement
\end{verbatim}
In totaal worden er bij bovenstaande parameters dus 700 metingen
gedaan: 100 verschillende berichtgroottes, telkens met 10000 eenheden verschil
in grootte (een enkele eenheid is een \texttt{double}), en elke meting wordt 7
maal herhaald waarbij de kleinste van die 7 metingen als resultaat wordt
genomen. Het resultaat wordt gedeeld door het aantal nodes in de ring, omdat
de latency is gedefiniëerd over een enkel communicatiekanaal.

\subsection{Gebruik}

Het programma wordt gestart met het shellscript \emph{ring.sh}. Aan dit
programma worden geen parameters meegegeven. Indien het programma is
gecompileerd met de \texttt{DEBUG} definitie in het bestand \emph{ring.c} zal
leesbare uitvoer worden gegeven, wat vooral is gebruikt tijdens de debug-fase.
Als de \texttt{DEBUG} definitie wordt weggelaten, zal het programma direct
getallen als uitvoer geven, bedoeld als invoer voor het programma
\emph{plot.py} die de data in een grafiek uitzet en een Least Squares fit
berekent. \emph{plot.py} heeft als optionele parameter een bestandsnaam om de
grafiek in op de slaan. Het gebruik van het programma is als volgt bedoeld:
\begin{verbatim}
$ ./ring.sh 6 | ./plot.py              # Laat alleen een grafiek zien
$ ./ring.sh 6 | ./plot.py results.pdf  # Slaat de grafiek ook op
\end{verbatim}

\section{Resultaten}

Het programma is uitgevoerd op het UvA-netwerk, de resultaten hiervan staan in
figuur \ref{fig:ring}. De formule van de Least Squares oplossing geeft ons een
latency van $579 \mu s$ en een throughput van $6.83 \cdot 10^{-8} s/eenheid$.
De throughput is beter leesbaar als het wordt geschreven in hoeveelheid per
tijdseenheid:

Een eenheid is de grootte van een double, welke 8 bytes groot is, dus de
througput is gelijk aan $8 \times 6.83 \cdot 10^{-8} = 5.46 \cdot 10^{-7}
s/byte = 14.6 \cdot 10^{6} byte/s = 14.0 Mbyte/s$.

\begin{figure}[H]
    \label{fig:ring}
    \includegraphics[width=14cm]{results.pdf}
    \caption{Metingen ringcommunicatie}
\end{figure}

\end{document}
