Parallel ausgeführte Programme haben das Ziel, dass Rechenzeit vermindert wird, wenn die Rechengeswchwindigkeit oder die Anzahl von Prozessen erhöht wird
## Speed-Up
Man geht von einem Algorithmus $A$ aus, welcher für die Ausführung auf einem einzelnen Prozessor die Zeit $t_1$ benötigt. Bei der Nutzung von $P$ Prozessoren mittels Parallelisierung benötigt der Prozessor die Zeit $t_P$. Nun kann der sogenannte Speedup $S_P$ mittels
$S_P = \frac{t_1}{t_P}$
berechnet werden. Bei konstanter Problemgröße $N$ sollte es idealerweise einen Speedup von $P$ geben. Die Realität sieht natürlich anders aus (Caching, Kommmunikation, serielle Anteile im Programm).
### Amdahlsches Gesetz
Jeder Algorithmus besteht aus Teilen, welche sich nicht parallelisieren lassen:
* serieller Anteil des Algorithmus: $s$
* paralleler Anteil des Algorithmus: $p$
* $s+p = 1$ (Normierung)
Somit lässt sich die Rechenzeit auf einem Prozessor durch $t_1 \rightarrow s+p$ und (bei idealem Verhalten) die Rechenzeit auf $P$ Prozessoren durch $t_P \rightarrow s + \frac{p}{P}$ ersetzen. Daraus folgt eine obere Schranke für den maximal erreichbaren Speedup von
$S_{\infty, Max} = 100$ ist die maximale Grenze. Doch die Frage liegt hier oft beim Kosten/Nutzen Verhältnis. Im ersten Schritt bringt eine Verzehnfachung der Prozessoren mehr als eine Verfünffachung der Geschwindigkeit. Im nächsten Schritt wird der Speedup jedoch noch nicht einmal verdoppelt.
Aber Vorsicht: echte Realität sieht anders aus: bei guten Algorithmen und kleinen Prozessorzahlen ist ein Speedup $S_P > p$ (superlinear) erreichbar. Bei hoher Kommunikation sieht es andererseits noch schlechter aus. Außerdem liegen die Bedingungen günstiger, wenn die Problemgröße steigt. Der serielle Anteil sinkt mit steigendem $N$.
## Scale-Up
Scale-Up bezeichnet die Eigenschaftm, dass es durch Parallelisierung möglich ist, bei gleicher Rechenzeit mehr Daten zu verarbeiten. Das bedeutet bei ursprünglicher Datenmenge $n_1$ kann eine Datenmenge $n_P$ genutzt werden, wobei die Rechenzeit $T$ konstant bleibt. Dann bezeichnet man als Scaleup den Zuwachs der Problemgröße mit
$C = \frac{n_P}{n_1}$
auch hier gibt es natürlich serielle und parallele Datenanteile.
## Scaled Speed-up
Eine Möglichkeit, beide Messverfahren zu kombinieren ist der sogenannte scaled Speedup $SC_P$. Es gilt dabei die Annahme, dass der Algorithmus optimal bzgl. der Problemgröße ist: $O(N)$ und zusätzlich
* Ausführungszeit auf $P$ Prozessoren: $s + p$
* Ausführungszeit auf einem Prozessor: $s + P\cdot p$
gilt. Dann ist der scaled Speedup
$SC_P = \frac{s+P\cdot p}{s+p} = s+P\cdot(1-s)$
da der serielle Anteil mit der Problemgröße abnimmt.
## Effizienz
Die parallele Effizienz eines Algorithmus berechnet sich durch $E = \frac{S_P}{P}$ (Die Effizienz des Scaleup und des scaled Speedups berechnet sich analog)
Eine Effizienz von 100% wäre ideal. Die Verwendung von $P$ Prozessoren beschleunigt die Abarbeitung auf das $P$-fache.
1. Führen Sie auf den HPC-Rechnern mittels MPI (und verschiedenen zusätzlichem Threading-Konstellationen) Ihr Programm aus und benchmarken Sie. Nutzen Sie dabei Timer-Funktionen von MPI.
2. Bereiten Sie sämtliche Ergebnisse in einer Tabelle auf und erstellen Sie Diagramme, welche sämtliche Daten bei verschiedensten Konstellationen miteinander sinnvoll darstellt.