Commit d6f87998 authored by Taddeüs Kroes's avatar Taddeüs Kroes

ModSim ass4 taddeus: Added reports for both parts.

parent 20e40ac2
CC=gcc
CFLAGS=-Wall -Wextra -pedantic -std=c99 -D_GNU_SOURCE -g -O0
LFLAGS=-lm
all: q1 q2 q3 q4 q5 q6 q7 report.pdf
q%: q%.o
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
q2: bisection.o
q3: bisection.o regula_falsi.o newton_raphson.o
q4: bisection.o regula_falsi.o newton_raphson.o
q5: integral.o
q6: integral.o
%.pdf: %.tex
pdflatex $^
pdflatex $^
clean:
for i in `seq 7`; do \
rm -vf q$$i; \
done;
rm -vf *.o
...@@ -79,8 +79,6 @@ De vergelijking van de drie integratiemethoden kan worden uitgevoerd met: ...@@ -79,8 +79,6 @@ De vergelijking van de drie integratiemethoden kan worden uitgevoerd met:
$ sh ./compare_osc.sh $ sh ./compare_osc.sh
\end{verbatim} \end{verbatim}
\begin{figure}[H] \begin{figure}[H]
\includegraphics[scale=.5]{osc_euler.pdf} \includegraphics[scale=.5]{osc_euler.pdf}
\caption{Euler} \caption{Euler}
...@@ -195,6 +193,4 @@ Dit is logisch, want de arm reageert sneller als de delay kleiner is. ...@@ -195,6 +193,4 @@ Dit is logisch, want de arm reageert sneller als de delay kleiner is.
\subsection{Gilpin's Model} \subsection{Gilpin's Model}
\end{document} \end{document}
\documentclass[a4paper]{article}
\usepackage{float,url}
\usepackage[dutch]{babel}
\title{Modelleren, simuleren \& continu\"e wiskunde -
Assignment 4: Parallel Computing}
\author{Tadde\"us Kroes (6054129)}
\begin{document}
\maketitle
\section{Theorie}
\section{Methoden}
\section{Resultaten}
\end{document}
CC=mpicc CC=mpicc
CFLAGS=-Wall -Wextra -pedantic -std=c99 -O0 CFLAGS=-Wall -Wextra -pedantic -std=c99 -O0 -lm
all: test ring all: test ring
test: ring_test.o test: ring_test.o
......
...@@ -16,10 +16,10 @@ start, slope = tuple(list(dot((A.T * A).I * A.T, b).tolist()[0])) ...@@ -16,10 +16,10 @@ start, slope = tuple(list(dot((A.T * A).I * A.T, b).tolist()[0]))
# Plot and optionally save data # Plot and optionally save data
data = data.T data = data.T
plot(data[0], data[1], 'x-', label='original data') plot(data[0], data[1], 'x', label='original data')
plot([0, data[0][-1]], [start, data[0][-1] * slope + start], '-', plot([0, data[0][-1]], [start, data[0][-1] * slope + start], '-',
label='linear fit y = %ex + %e' % (slope, start)) label='linear fit y = %ex + %e' % (slope, start))
legend()
if len(argv) == 2: if len(argv) == 2:
savefig(argv[1]) savefig(argv[1])
legend()
show() show()
\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 - 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$.
% TODO: Check value above
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}
$ sh ring.sh | python plot.py # Laat alleen een grafiek zien
$ sh ring.sh | python 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 $...$ seconde en een throughput van $...$ eenheden per seconde.
Een eenheid is de grootte van een double, welke 8 bytes groot is, dus de
througput is gelijk aan $8 \times ... = ... bytes/sec$.
% TODO: Fill in values above
\begin{figure}[H]
\label{fig:ring}
\includegraphics[width=15cm]{ring.pdf}
\caption{Metingen ringcommunicatie}
\end{figure}
\end{document}
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <math.h>
#include <mpi.h> #include <mpi.h>
//#define DEBUG #define DEBUG
#define LOOP 100 // Number of different message sizes #define LOOP 1 // Number of different message sizes
#define STRIDE 10000 // Difference between the message sizes #define STRIDE 10000 // Difference between the message sizes
#define REPEAT 7 // Number of times to repeat a measurement #define REPEAT 7 // Number of times to repeat aREPEAT measurement
const int data_size = LOOP * STRIDE; const int data_size = LOOP * STRIDE;
...@@ -17,7 +18,7 @@ const int data_size = LOOP * STRIDE; ...@@ -17,7 +18,7 @@ const int data_size = LOOP * STRIDE;
void master(int tasks) { void master(int tasks) {
double *received = malloc(data_size * sizeof(double)), double *received = malloc(data_size * sizeof(double)),
*sent = malloc(data_size * sizeof(double)), *sent = malloc(data_size * sizeof(double)),
avg_time, start_time, time; avg_time, min_time, start_time, time;
MPI_Status status; MPI_Status status;
int i, size, measurement, failures; int i, size, measurement, failures;
...@@ -25,10 +26,16 @@ void master(int tasks) { ...@@ -25,10 +26,16 @@ void master(int tasks) {
for( i = 0; i < data_size; i++ ) for( i = 0; i < data_size; i++ )
sent[i] = (double)i; sent[i] = (double)i;
#ifdef DEBUG
printf("Using a ring of %d nodes, time precision is %fs, unit size is %d "
"bytes.\n", tasks, MPI_Wtick(), sizeof(double));
#endif
// Increase the message length with a fixed STRIDE // Increase the message length with a fixed STRIDE
for( size = STRIDE; size <= data_size; size += STRIDE ) { for( size = STRIDE; size <= data_size; size += STRIDE ) {
// Repeat the measurement and average the results // Repeat the measurement and average the results
avg_time = .0; avg_time = .0;
min_time = INFINITY;
for( measurement = 1; measurement <= REPEAT; measurement++ ) { for( measurement = 1; measurement <= REPEAT; measurement++ ) {
#ifdef DEBUG #ifdef DEBUG
...@@ -50,14 +57,21 @@ void master(int tasks) { ...@@ -50,14 +57,21 @@ void master(int tasks) {
printf("%fs (%d failures)\n", time, failures); printf("%fs (%d failures)\n", time, failures);
#endif #endif
avg_time += time; avg_time += time;
if( time < min_time )
min_time = time;
} }
avg_time /= REPEAT; // Divide by node count now instead of inside the loop to preserve
// maximum accuracy
avg_time /= REPEAT * tasks;
min_time /= tasks;
#ifdef DEBUG #ifdef DEBUG
printf("Average time for size %d: %fs\n", size, avg_time); printf("Average and minimum time for size %d: %fs, %fs\n", size,
avg_time, min_time);
#else #else
printf("%d,%f\n", size, avg_time); printf("%d,%f\n", size, min_time);
#endif #endif
} }
......
#!/bin/sh #!/bin/sh
NUM_PROCESSES=4 NUM_PROCESSES=${1-4} # Default: 4 processes
RSH_AGENT=rsh RSH_AGENT=rsh
MPI_HOSTFILE=~/.mpirun.machines MPI_HOSTFILE=~/.mpirun.machines
PROGRAM_EXEC=ring PROGRAM_EXEC=ring
......
...@@ -15,14 +15,11 @@ max_y = max([max(map(abs, y[i])) for i in range(len(y))]) ...@@ -15,14 +15,11 @@ max_y = max([max(map(abs, y[i])) for i in range(len(y))])
ranges = [0, max(x), -max_y, max_y] ranges = [0, max(x), -max_y, max_y]
# Plot data in animation # Plot data in animation
try: ion()
ion() figure(1)
figure(1) for i in range(len(y)):
for i in range(len(y)):
clf() clf()
plot(x, y[i], '-') plot(x, y[i], '-')
axis(ranges) axis(ranges)
draw() draw()
sleep(.01) sleep(.01)
except KeyboardInterrupt:
print 'Quitting...'
all: report.pdf
report.pdf: report.tex
pdflatex $^
pdflatex $^
clean:
rm *.pdf *.log *.aux
\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 - Trillende snaar}
\author{Tadde\"us Kroes (6054129)}
\begin{document}
\maketitle
\tableofcontents
\pagebreak
\section{Inleiding}
\section{Theorie}
\section{Implementatie}
\subsection{Gebruik}
\section{Resultaten}
%\begin{figure}[H]
% \label{fig:sinus}
% \includegraphics[width=15cm]{sinus.pdf}
% \caption{Resultaten met de ``sinus''-initialisatiemethode.}
%\end{figure}
%\begin{figure}[H]
% \label{fig:plucked}
% \includegraphics[width=15cm]{plucked.pdf}
% \caption{Resultaten met de ``plucked''-initialisatiemethode.}
%\end{figure}
\end{document}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment