https://de.wikipedia.org/w/api.php?action=feedcontributions&feedformat=atom&user=RenderFlamingo Wikipedia - Benutzerbeiträge [de] 2025-06-12T04:35:43Z Benutzerbeiträge MediaWiki 1.45.0-wmf.4 https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197393248 Kollektive Operationen 2020-03-03T21:14:09Z <p>RenderFlamingo: RenderFlamingo verschob die Seite Benutzer:RenderFlamingo/Kollektive Kommunikation nach Kollektive Operationen: Artikel fertig.</p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben. Habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;.<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Die vorgestellten Konzepte sind im Modell eines geteilten Speichers ähnlich. Bei geteiltem Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Informationsfluss von Broadcast ausgeführt auf drei Einheiten.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in [[Single-Program Multiple-Data|SPMD]] parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ([[#Reduktion]]) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung, die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz, der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt, verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Informationsfluss von Reduktion ausgeführt auf drei Einheite. f sei ein assoziativer Operator und α sei das Resultat der Reduktion.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ([[#Broadcast]]) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um Pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion möglich ist.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Informationsfluss von All-Reduce ausgeführt auf drei Einheiten. f sei ein assoziativer Operator und α sei das Resultat der Reduktion.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion ([[#Reduktion]]) allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast ([[#Broadcast]]). Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> <br /> {{Absatz}}<br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Informationsfluss von Prefix-Sum/Scan ausgeführt auf drei Einheiten. Der Operator + kann ein beliebiger assoziativer Operator sein.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion ([[#Reduktion]]) aufgefasst werden. Wie in Reduktion und All-reduce ([[#All-reduce]]) wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;sum, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein [[Bin%C3%A4rbaum|Binärbaum]] in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast ([[#Broadcast]]). Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltem Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ([[#All-reduce]]) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Informationsfluss von Gather ausgeführt auf drei Einheiten.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ([[#Reduktion]]) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; der Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> {{Absatz}}<br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Informationsfluss von All-Gather ausgeführt auf drei Einheiten.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> {{Absatz}}<br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|upright=1.8|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Informationsfluss von Scatter ausgeführt auf drei Einheiten.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather ([[#Gather]]) gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster, die keine Operation benötigen, lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt;, kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]] eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|upright=1.4|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Informationsfluss von All-to-All ausgeführt auf drei Einheiten. Buchstaben indizieren Einheiten und Nummern indizieren Informationselemente.]]<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus [[Bin%C3%A4rbaum|Binärbaum]], [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] und [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]].<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum, während für lange Nachrichten Kommunikation, die Pipelining verwendet, auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten, die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> {{Absatz}}<br /> == Anmerkungen ==<br /> &lt;references /&gt; <br /> <br /> == Einzelnachweise ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}<br /> [[Kategorie:Parallelverarbeitung]]<br /> [[Kategorie:Algorithmus]]<br /> [[Kategorie:Verteiltes Rechnen]]</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197393170 Kollektive Operationen 2020-03-03T21:11:16Z <p>RenderFlamingo: </p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben. Habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;.<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Die vorgestellten Konzepte sind im Modell eines geteilten Speichers ähnlich. Bei geteiltem Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Informationsfluss von Broadcast ausgeführt auf drei Einheiten.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in [[Single-Program Multiple-Data|SPMD]] parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ([[#Reduktion]]) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung, die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz, der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt, verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Informationsfluss von Reduktion ausgeführt auf drei Einheite. f sei ein assoziativer Operator und α sei das Resultat der Reduktion.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ([[#Broadcast]]) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um Pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion möglich ist.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Informationsfluss von All-Reduce ausgeführt auf drei Einheiten. f sei ein assoziativer Operator und α sei das Resultat der Reduktion.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion ([[#Reduktion]]) allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast ([[#Broadcast]]). Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> <br /> {{Absatz}}<br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Informationsfluss von Prefix-Sum/Scan ausgeführt auf drei Einheiten. Der Operator + kann ein beliebiger assoziativer Operator sein.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion ([[#Reduktion]]) aufgefasst werden. Wie in Reduktion und All-reduce ([[#All-reduce]]) wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;sum, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein [[Bin%C3%A4rbaum|Binärbaum]] in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast ([[#Broadcast]]). Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltem Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ([[#All-reduce]]) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Informationsfluss von Gather ausgeführt auf drei Einheiten.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ([[#Reduktion]]) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; der Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> {{Absatz}}<br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Informationsfluss von All-Gather ausgeführt auf drei Einheiten.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> {{Absatz}}<br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|upright=1.8|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Informationsfluss von Scatter ausgeführt auf drei Einheiten.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather ([[#Gather]]) gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster, die keine Operation benötigen, lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt;, kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]] eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|upright=1.4|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Informationsfluss von All-to-All ausgeführt auf drei Einheiten. Buchstaben indizieren Einheiten und Nummern indizieren Informationselemente.]]<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus [[Bin%C3%A4rbaum|Binärbaum]], [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] und [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]].<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum, während für lange Nachrichten Kommunikation, die Pipelining verwendet, auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten, die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> {{Absatz}}<br /> == Anmerkungen ==<br /> &lt;references /&gt; <br /> <br /> == Einzelnachweise ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}<br /> [[Kategorie:Parallelverarbeitung]]<br /> [[Kategorie:Algorithmus]]<br /> [[Kategorie:Verteiltes Rechnen]]</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197392437 Kollektive Operationen 2020-03-03T20:47:36Z <p>RenderFlamingo: </p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben. Habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;.<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Die vorgestellten Konzepte sind im Modell eines geteilten Speichers ähnlich. Bei geteiltem Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Information flow of Broadcast operation performed on three nodes.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in [[Single-Program Multiple-Data|SPMD]] parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ([[#Reduktion]]) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung, die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz, der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt, verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ([[#Broadcast]]) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um Pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion möglich ist.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of All-Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion ([[#Reduktion]]) allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast ([[#Broadcast]]). Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> <br /> {{Absatz}}<br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Information flow of Prefix-Sum/Scan operation performed on three nodes. The operator + can be any associative operator.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion ([[#Reduktion]]) aufgefasst werden. Wie in Reduktion und All-reduce ([[#All-reduce]]) wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;sum, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein [[Bin%C3%A4rbaum|Binärbaum]] in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast ([[#Broadcast]]). Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltem Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ([[#All-reduce]]) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Information flow of Gather operation performed on three nodes.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ([[#Reduktion]]) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; der Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> {{Absatz}}<br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Information flow of All-Gather operation performed on three nodes.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> {{Absatz}}<br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|upright=1.8|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Information flow of Scatter operation performed on three nodes.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather ([[#Gather]]) gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster, die keine Operation benötigen, lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt;, kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]] eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|upright=1.4|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Information flow of All-to-All operation performed on three nodes. Letters indicate nodes and numbers indicate information items.]]<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus [[Bin%C3%A4rbaum|Binärbaum]], [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] und [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]].<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum, während für lange Nachrichten Kommunikation, die Pipelining verwendet, auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten, die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> {{Absatz}}<br /> == Anmerkungen ==<br /> &lt;references /&gt; <br /> <br /> == Einzelnachweise ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}<br /> [[Kategorie:Parallelverarbeitung]]<br /> [[Kategorie:Algorithmus]]<br /> [[Kategorie:Verteiltes Rechnen]]</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197392413 Kollektive Operationen 2020-03-03T20:46:45Z <p>RenderFlamingo: </p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben. Habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;.<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Die vorgestellten Konzepte sind im Modell eines geteilten Speichers ähnlich. Bei geteiltem Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Information flow of Broadcast operation performed on three nodes.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in [[Single-Program Multiple-Data|SPMD]] parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ([[#Reduktion]]) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung, die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz, der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt, verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ([[#Broadcast]]) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um Pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion möglich ist.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of All-Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion ([[#Reduktion]]) allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast ([[#Broadcast]]). Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> <br /> {{Absatz}}<br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Information flow of Prefix-Sum/Scan operation performed on three nodes. The operator + can be any associative operator.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion ([[#Reduktion]]) aufgefasst werden. Wie in Reduktion und All-reduce ([[#All-reduce]]) wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;sum, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein [[Bin%C3%A4rbaum|Binärbaum]] in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast ([[#Broadcast]]). Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltem Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ([[#All-reduce]]) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Information flow of Gather operation performed on three nodes.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ([[#Reduktion]]) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; der Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> {{Absatz}}<br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Information flow of All-Gather operation performed on three nodes.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> {{Absatz}}<br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|upright=1.8|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Information flow of Scatter operation performed on three nodes.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather ([[#Gather]]) gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster, die keine Operation benötigen, lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt;, kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]] eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|upright=1.4|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Information flow of All-to-All operation performed on three nodes. Letters indicate nodes and numbers indicate information items.]]<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus [[Bin%C3%A4rbaum|Binärbaum]], [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] und [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]].<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum, während für lange Nachrichten Kommunikation, die Pipelining verwendet, auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten, die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> == Anmerkungen ==<br /> &lt;references /&gt; <br /> <br /> == Einzelnachweise ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}<br /> [[Kategorie:Parallelverarbeitung]]<br /> [[Kategorie:Algorithmus]]<br /> [[Kategorie:Verteiltes Rechnen]]</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197392345 Kollektive Operationen 2020-03-03T20:44:39Z <p>RenderFlamingo: </p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben. Habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;.<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Die vorgestellten Konzepte sind im Modell eines geteilten Speichers ähnlich. Bei geteiltem Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Information flow of Broadcast operation performed on three nodes.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in [[Single-Program Multiple-Data|SPMD]] parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ([[#Reduktion]]) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung, die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz, der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt, verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ([[#Broadcast]]) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um Pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion möglich ist.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|upright=1.2|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of All-Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion ([[#Reduktion]]) allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast ([[#Broadcast]]). Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> <br /> {{Absatz}}<br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Information flow of Prefix-Sum/Scan operation performed on three nodes. The operator + can be any associative operator.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion ([[#Reduktion]]) aufgefasst werden. Wie in Reduktion und All-reduce ([[#All-reduce]]) wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;sum, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein [[Bin%C3%A4rbaum|Binärbaum]] in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast ([[#Broadcast]]). Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{Absatz}}<br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltem Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ([[#All-reduce]]) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Information flow of Gather operation performed on three nodes.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ([[#Reduktion]]) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; der Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> {{Absatz}}<br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|upright=1.8|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Information flow of All-Gather operation performed on three nodes.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> {{Absatz}}<br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|upright=1.8|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Information flow of Scatter operation performed on three nodes.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather ([[#Gather]]) gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> {{Absatz}}<br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster, die keine Operation benötigen, lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt;, kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]] eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|upright=1.4|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Information flow of All-to-All operation performed on three nodes. Letters indicate nodes and numbers indicate information items.]]<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus [[Bin%C3%A4rbaum|Binärbaum]], [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] und [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]].<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum, während für lange Nachrichten Kommunikation, die Pipelining verwendet, auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten, die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> == Anmerkungen ==<br /> &lt;references /&gt; <br /> <br /> == Einzelnachweise ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197391547 Kollektive Operationen 2020-03-03T20:19:51Z <p>RenderFlamingo: </p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben. Habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;.<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Die vorgestellten Konzepte sind im Modell eines geteilten Speichers ähnlich. Bei geteiltem Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Information flow of Broadcast operation performed on three nodes.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in [[Single-Program Multiple-Data|SPMD]] parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ([[#Reduktion]]) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung, die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz, der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt, verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> <br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ([[#Broadcast]]) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um Pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion möglich ist.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of All-Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion ([[#Reduktion]]) allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast ([[#Broadcast]]). Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> <br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Information flow of Prefix-Sum/Scan operation performed on three nodes. The operator + can be any associative operator.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion ([[#Reduktion]]) aufgefasst werden. Wie in Reduktion und All-reduce ([[#All-reduce]]) wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;sum, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein [[Bin%C3%A4rbaum|Binärbaum]] in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast ([[#Broadcast]]). Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltem Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ([[#All-reduce]]) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Information flow of Gather operation performed on three nodes.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ([[#Reduktion]]) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; der Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Information flow of All-Gather operation performed on three nodes.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Information flow of Scatter operation performed on three nodes.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather ([[#Gather]]) gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster, die keine Operation benötigen, lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt;, kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]] eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Information flow of All-to-All operation performed on three nodes. Letters indicate nodes and numbers indicate information items.]]<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus [[Bin%C3%A4rbaum|Binärbaum]], [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] und [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]].<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum, während für lange Nachrichten Kommunikation, die Pipelining verwendet, auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten, die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> == Anmerkungen ==<br /> &lt;references /&gt; <br /> <br /> == Einzelnachweise ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197391322 Kollektive Operationen 2020-03-03T20:14:00Z <p>RenderFlamingo: </p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben. Habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;.<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Die vorgestellten Konzepte sind im Modell eines geteilten Speichers ähnlich. Bei geteiltem Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Information flow of Broadcast operation performed on three nodes.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in [[Single-Program Multiple-Data|SPMD]] parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ([[#Reduktion]]) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung, die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz, der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt, verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> <br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ([[#Broadcast]]) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um Pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion möglich ist.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of All-Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion ([[#Reduktion]]) allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast ([[#Broadcast]]). Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> <br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Information flow of Prefix-Sum/Scan operation performed on three nodes. The operator + can be any associative operator.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion ([[#Reduktion]]) aufgefasst werden. Wie in Reduktion und All-reduce ([[#All-reduce]]) wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;sum, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein [[Bin%C3%A4rbaum|Binärbaum]] in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast ([[#Broadcast]]). Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltem Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ([[#All-reduce]]) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Information flow of Gather operation performed on three nodes.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ([[#Reduktion]]) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; der Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Information flow of All-Gather operation performed on three nodes.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Information flow of Scatter operation performed on three nodes.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather ([[#Gather]]) gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster, die keine Operation benötigen, lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt;, kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]] eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Information flow of All-to-All operation performed on three nodes. Letters indicate nodes and numbers indicate information items.]]<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus [[Bin%C3%A4rbaum|Binärbaum]], [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] und [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]].<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum, während für lange Nachrichten Kommunikation, die Pipelining verwendet, auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten, die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> == References ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197390574 Kollektive Operationen 2020-03-03T19:49:35Z <p>RenderFlamingo: </p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben. Habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;.<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Die vorgestellten Konzepte sind im Modell eines geteilten Speichers ähnlich. Bei geteiltem Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Information flow of Broadcast operation performed on three nodes.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in [[Single-Program Multiple-Data|SPMD]] parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ([[#Reduktion]]) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung, die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz, der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt, verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> <br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ([[#Broadcast]]) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um Pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion möglich ist.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of All-Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion ([[#Reduktion]]) allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast ([[#Broadcast]]). Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> <br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Information flow of Prefix-Sum/Scan operation performed on three nodes. The operator + can be any associative operator.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion ([[#Reduktion]]) aufgefasst werden. Wie in Reduktion und All-reduce ([[#All-reduce]]) wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;sum, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein [[Bin%C3%A4rbaum|Binärbaum]] in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast ([[#Broadcast]]). Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltem Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ([[#All-reduce]]) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Information flow of Gather operation performed on three nodes.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ({{section link||Reduktion}}) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; see Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> {{clear}}<br /> <br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Information flow of All-Gather operation performed on three nodes.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> {{clear}}<br /> <br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Information flow of Scatter operation performed on three nodes.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> {{clear}}<br /> <br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster die keine Operation benötigen lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt emuliert werden, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt; kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen Hyperwürfel eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Information flow of All-to-All operation performed on three nodes. Letters indicate nodes and numbers indicate information items.]]<br /> <br /> {{clear}}<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus Binärbaum, Binomialbaum und Hyperwürfel.<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum während für lange Nachrichten Kommunikation die Pipelining verwendet auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> == References ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197390133 Kollektive Operationen 2020-03-03T19:33:46Z <p>RenderFlamingo: </p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben. Habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;.<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Die vorgestellten Konzepte sind im Modell eines geteilten Speichers ähnlich. Bei geteiltem Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Information flow of Broadcast operation performed on three nodes.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in [[Single-Program Multiple-Data|SPMD]] parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion () aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung, die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz, der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt, verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> <br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ({{section link||Broadcast}}) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um Pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion möglich ist.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of All-Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast. Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> {{clear}}<br /> <br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Information flow of Prefix-Sum/Scan operation performed on three nodes. The operator + can be any associative operator.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion aufgefasst werden. Wie in Reduktion und All-reduce wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;SUM, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine Hyperwürfel-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein Binärbaum in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast. Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{clear}}<br /> <br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltes Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ({{section link||All-reduce}}) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Information flow of Gather operation performed on three nodes.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ({{section link||Reduktion}}) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; see Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> {{clear}}<br /> <br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Information flow of All-Gather operation performed on three nodes.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> {{clear}}<br /> <br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Information flow of Scatter operation performed on three nodes.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> {{clear}}<br /> <br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster die keine Operation benötigen lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt emuliert werden, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt; kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen Hyperwürfel eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Information flow of All-to-All operation performed on three nodes. Letters indicate nodes and numbers indicate information items.]]<br /> <br /> {{clear}}<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus Binärbaum, Binomialbaum und Hyperwürfel.<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum während für lange Nachrichten Kommunikation die Pipelining verwendet auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> == References ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197361475 Kollektive Operationen 2020-03-02T23:59:17Z <p>RenderFlamingo: </p> <hr /> <div>'''Kollektive Operationen''' sind Grundbausteine für Interaktionsmuster, die häufig Anwendung in [[Single-Program_Multiple-Data|SPMD]] Algorithmen und [[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message Passing Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine Realisierung der kollektiven Operationen bereit.<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die Kommunikationszeit pro Wort &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen, die mit Nachrichten auf verschiedenen Prozessoreinheiten starten, nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen, verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben, habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Dieses Modell ist konzeptionell ähnlich zum Modell eines geteilten Speichers. Bei geteilten Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Information flow of Broadcast operation performed on three nodes.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in SPMD parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ({{section link||Reduktion}}) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> {{clear}}<br /> <br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ({{section link||Broadcast}}) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion durchgeführt werden kann.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{clear}}<br /> <br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of All-Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast. Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> {{clear}}<br /> <br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Information flow of Prefix-Sum/Scan operation performed on three nodes. The operator + can be any associative operator.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion aufgefasst werden. Wie in Reduktion und All-reduce wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;SUM, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine Hyperwürfel-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein Binärbaum in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast. Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{clear}}<br /> <br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltes Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ({{section link||All-reduce}}) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Information flow of Gather operation performed on three nodes.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ({{section link||Reduktion}}) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; see Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> {{clear}}<br /> <br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Information flow of All-Gather operation performed on three nodes.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> {{clear}}<br /> <br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Information flow of Scatter operation performed on three nodes.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> {{clear}}<br /> <br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster die keine Operation benötigen lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt emuliert werden, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt; kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen Hyperwürfel eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Information flow of All-to-All operation performed on three nodes. Letters indicate nodes and numbers indicate information items.]]<br /> <br /> {{clear}}<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus Binärbaum, Binomialbaum und Hyperwürfel.<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum während für lange Nachrichten Kommunikation die Pipelining verwendet auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> == References ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}</div> RenderFlamingo https://de.wikipedia.org/w/index.php?title=Kollektive_Operationen&diff=197361334 Kollektive Operationen 2020-03-02T23:46:24Z <p>RenderFlamingo: AZ: Die Seite wurde neu angelegt: Kollektive Operationen sind Grundbausteine für Interaktionsmuster die häufige Anwendung in Single-…</p> <hr /> <div>Kollektive Operationen sind Grundbausteine für Interaktionsmuster die häufige Anwendung in [[Single-Program_Multiple-Data|SPMD]] [[Algorithmus|Algorithmen]]und parelleler Programmierung[[Parallele_Programmierung|paralleler Programmierung]] finden. Dadurch entsteht die Notwendigkeit, diese Operationen effizient zu realisieren.<br /> <br /> Das [[Message_Passing_Interface]]&lt;ref&gt;[http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node144.htm Intercommunicator Collective Operations]. The Message Passing Interface (MPI) standard, chapter 7.3.1. Mathematics and Computer Science Division, [[Argonne National Laboratory]].&lt;/ref&gt; (MPI) stellt eine [[Implementierung]] der kollektiven Operationen bereit. DSC<br /> <br /> == Definitionen ==<br /> In der [[Landau-Symbole|asymptotischen Laufzeitanalyse]] sei die [[Verz%C3%B6gerung_(Telekommunikation)|Latenz]] &lt;math&gt;\alpha&lt;/math&gt;, die [[Bandbreite]] &lt;math&gt;\beta&lt;/math&gt;, die Anzahl der Prozessoreinheiten &lt;math&gt;p&lt;/math&gt; und die Größe der Eingabe pro Knoten &lt;math&gt;n&lt;/math&gt;. Für Operationen die mit Nachrichten auf verschiedenen Prozessoreinheiten starten nehmen wir an, dass alle lokalen Nachrichten die gleiche Größe haben. Um einzelne Prozessoreinheiten zu bezeichnen verwenden wir &lt;math&gt;p_i \in \{ p_0, p_1, \dots, p_{p - 1} \}&lt;/math&gt;. <br /> <br /> Aus den angegebenen Laufzeiten lässt sich eine obere Schranke für den Fall bestimmen, dass die initialen Nachrichten unterschiedliche Größen haben, habe Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; eine Nachricht der Größe &lt;math&gt;n_i&lt;/math&gt;. Dann setze man &lt;math&gt;n = \max(n_0, n_1, \dots, n_{p-1})&lt;/math&gt;<br /> <br /> Es wird das Modell eines verteilten Speichers angenommen. Dieses Modell ist konzeptionell ähnlich zum Modell eines geteilten Speichers. Bei geteilten Speicher besteht jedoch die Möglichkeit, dass die Hardware Operationen wie Broadcast unmittelbar unterstützt &lt;ref name=&quot;:1&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 395&lt;/ref&gt;. Diese Unterstützung öffnet in der Entwicklung von Algorithmen zusätzliche Möglichkeiten.<br /> <br /> == Broadcast &lt;ref name=&quot;:2&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 396-401&lt;/ref&gt;==<br /> {{Main|Broadcast}}<br /> <br /> [[File:Broadcast_(collective_operation).png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left and high right square. Two solid lines connect the high left square and the middle and low right sqaure. The letter a is written in the high left square and in all right squares.|thumb|Information flow of Broadcast operation performed on three nodes.]]<br /> <br /> Das Broadcast-Muster wird genutzt, um Daten einer Prozessoreinheit an alle anderen Prozessoreinheiten zu verteilen. Ein Anwendungsfall des Broadcast ist, in SPMD parallelen Programmen Eingaben und globale Variablen zu verteilen. Der Broadcast kann als inverse Reduktion ({{section link||Reduktion}}) aufgefasst werden. Zu Beginn enthält die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; für ein festes &lt;math&gt;i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt;. Hier nehmen wir &lt;math&gt;i = 0&lt;/math&gt; an, um die Erklärung simpler zu gestalten. Während des Broadcast wird &lt;math&gt;m&lt;/math&gt; an die restlichen Prozessoreinheiten gesendet, sodass &lt;math&gt;m&lt;/math&gt; schlussendlich auf allen Prozessoreinheiten verfügbar ist.<br /> <br /> Da die triviale Implementierung die in &lt;math&gt;p-1&lt;/math&gt; Iterationen jeweils &lt;math&gt;m&lt;/math&gt; direkt von &lt;math&gt;r&lt;/math&gt; an &lt;math&gt;p_j&lt;/math&gt; übermittelt, nicht ausreichend performant ist, wird ein Ansatz der das Prinzip '[[Teile-und-herrsche-Verfahren|Teile-und-herrsche-Verfahren]]' nutzt verwendet. Sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist, kann ein [[Binomial-Heap#Binomial-B%C3%A4ume|Binomialbaum]] als unterliegende Struktur verwendet werden. Angenommen Prozessoreinheit &lt;math&gt;p_k&lt;/math&gt; ist verantwortlich, die Nachricht an Prozessoreinheiten &lt;math&gt;p_l, ..., p_n&lt;/math&gt; weiterzuleiten. Dann sendet &lt;math&gt;p_k&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; an &lt;math&gt;p_o&lt;/math&gt; mit &lt;math&gt;o = \left \lceil (i+j)/2 \right \rceil&lt;/math&gt;. Die Verantwortung für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an Prozessoreinheiten mit Indizes &lt;math&gt;\left \lceil (i+j)/2 \right \rceil .. \left \lceil (i+j)-1 \right \rceil&lt;/math&gt; wird an &lt;math&gt;p_o&lt;/math&gt; übertragen, &lt;math&gt;p_k&lt;/math&gt; ist im Folgenden nur noch für die Übermittlung von &lt;math&gt;m&lt;/math&gt; an die Prozessoreinheiten mit Indizes &lt;math&gt;i..\left \lceil (i+j)/2 \right \rceil-1&lt;/math&gt; zuständig. Die Performance des Binomialbaum-Broadcast ist für lange Nachrichten nicht gut, da eine Prozessoreinheit, die &lt;math&gt;m&lt;/math&gt; empfängt, erst dann die Nachricht weiterleiten kann, wenn &lt;math&gt;m&lt;/math&gt; vollständig empfangen wurde. Als Ausgleich wird Pipelining verwendet. Dabei wird &lt;math&gt;m&lt;/math&gt; in ein [[Feld_(Datentyp)|Array]] aus &lt;math&gt;k&lt;/math&gt; [[Datenpaket|Paketen]] der Größe &lt;math&gt;\left \lceil n/k \right \rceil &lt;/math&gt; zerlegt. Die Pakete werden dann nacheinander per Broadcast verteilt, was bessere Auslastung des Kommunikationsnetzes erlaubt.<br /> <br /> Broadcast mit Pipelining auf einem balancierten [[Bin%C3%A4rbaum|Binärbaum]] ist in Laufzeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; möglich.<br /> {{clear}}<br /> <br /> == Reduktion &lt;ref name=&quot;:3&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 402-403&lt;/ref&gt;==<br /> <br /> [[File:Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster Reduktion wird genutzt, um Daten oder partielle Ergebnisse verschiedener Prozessoreinheiten zu sammeln und in ein globales Resultat zu vereinigen. Reduktion kann als inverse Operation zum Broadcast ({{section link||Broadcast}}) aufgefasst werden. Sei &lt;math&gt;\otimes&lt;/math&gt; ein [[Assoziativgesetz|assoziativer]] [[Operator_(Mathematik)|Operator]], &lt;math&gt;p_0&lt;/math&gt; die Prozessoreinheit auf der das Ergebnis gespeichert werden soll. Dann berechnet die Reduktion das Ergebnis &lt;math&gt;m_0 \otimes m_1 \otimes \ldots \otimes m_p&lt;/math&gt; und speichert es auf Prozessoreinheit &lt;math&gt;p_0&lt;/math&gt;. Manche Algorithmen fordern, dass &lt;math&gt;\otimes&lt;/math&gt; zusätzlich [[Kommutativgesetz|kommutativ]] ist. Häufige Operatoren sind &lt;math&gt;sum, min, max&lt;/math&gt;. <br /> <br /> Da Reduktion als inverser Broadcast aufgefasst werden kann, gelten die gleichen Randbedingungen für eine Implementierung. Um pipelining zu ermöglichen ist es wichtig, dass die Nachricht als Vektor kleinerer Objekte repräsentiert werden kann, sodass eine komponentenweise Reduktion durchgeführt werden kann.<br /> <br /> Reduktion mit Pipelining auf einem balancierten Binärbaum ist in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{clear}}<br /> <br /> == All-reduce &lt;ref name=&quot;:4&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 403-404&lt;/ref&gt;==<br /> <br /> [[File:All-Reduce.png|alt=There are three squares vertically aligned on the left and three squares vertically aligned on the right. A circle with the letter f inside is placed between the two columns. Three solid lines connect the circle with the left three squares. One solid line connects the circle and the high right square. The letters a, b and c are written in the left squares from high to low. The letter alpha is written in the top right square.|thumb|Information flow of All-Reduce operation performed on three nodes. f is the associative operator and α is the result of the reduction.]]<br /> <br /> Das Muster All-reduce wird genutzt, wenn das Ergebnis einer Reduktion allen Prozessoreinheiten zur Verfügung gestellt werden soll. Zu Beginn liegt auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt;. Das Ergebnis &lt;math&gt; m_1 \otimes m_2 \otimes \ldots \otimes m_p&lt;/math&gt; liegt nach dem All-reduce auf allen &lt;math&gt; p_i &lt;/math&gt; vor. Konzeptionell entspricht All-reduce einer Reduktion mit anschließendem Broadcast. Auch bei All-reduce muss &lt;math&gt;\otimes&lt;/math&gt; assoziativ sein.<br /> <br /> Für lange Nachrichten spielen die gleichen Randbedingungen eine Rolle. Für kurze Nachrichten kann die Latenz durch Nutzung einer [[Hyperw%C3%BCrfel_(Kommunikationsmuster)|Hyperwürfel]]-Topologie verbessert werden, sofern &lt;math&gt;p&lt;/math&gt; eine Zweierpotenz ist.<br /> <br /> Wir sehen, dass All-reduce in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich ist, da Reduktion und Broadcast jeweils in &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich sind.<br /> {{clear}}<br /> <br /> == Präfixsumme/Scan &lt;ref name=&quot;:5&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 404-406&lt;/ref&gt;==<br /> {{Main|Pr%C3%A4fixsumme}}<br /> <br /> [[File:Prefix-Sum_(Scan).png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A circle with the word scan inside is placed between the two columns. Three solid lines connect the circle with the left three squares. Three solid lines connect the circle with the three right square. The letters a, b and c are written in the left squares from high to low. In the high right square the letter a is written. In the mid right square the term a plus b is written. In the low right square the term a plus b plus c is written.|thumb|Information flow of Prefix-Sum/Scan operation performed on three nodes. The operator + can be any associative operator.]]<br /> <br /> Das Muster Präfixsumme oder Scan wird genutzt, um Daten oder partielle Resultate mehrerer Prozessoreinheiten zusammenzutragen und mittels eines Operators &lt;math&gt; \otimes &lt;/math&gt; Zwischenergebnisse zu berechnen. Die Zwischenergebnisse werden auf den einzelnen Prozessoreinheiten gespeichert. Die Präfixsumme kann als Generalisierung des Musters Reduktion aufgefasst werden. Wie in Reduktion und All-reduce wird vom Operator &lt;math&gt;\otimes&lt;/math&gt; mindestens Assoziativität gefordert, wobei manche Algorithmen zusätzlich Kommutativität erfordern. Häufige Operationen sind &lt;math&gt;SUM, min, max&lt;/math&gt;.<br /> <br /> Nach Abschluss der Präfixsumme enthält Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;\otimes_{i' &lt;= i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt;. Im Sonderfall der exklusiven Präfixsumme wird stattdessen &lt;math&gt;\otimes_{i' &lt; i}&lt;/math&gt;&lt;math&gt;m_{i'}&lt;/math&gt; berechnet. Manche Algorithmen fordern zudem, dass zusätzlich zur Präfixsumme auch die vollständige Summe auf jeder Prozessoreinheit gespeichert wird, dass also Präfixsumme und All-reduce kombiniert werden.<br /> <br /> Für kurze Nachrichten kann eine optimale Implementierung durch eine Hyperwürfel-Topologie erreicht werden. Für lange Nachrichten ist der Hyperwürfel nicht effektiv, da alle Prozessoreinheiten in jedem Schritt aktiv sind und dadurch Pipelining nicht angewendet werden kann. Für lange Nachrichten ist stattdessen ein Binärbaum in Kombination mit Pipelining besser geeignet. Dabei wird die Präfixsumme in eine Aufwärts- und eine Abwärts-Phase zerlegt. Die Reduktion findet in der Aufwärts-Phase statt. Die Abwärts-Phase ist ähnlich zum Broadcast. Dabei wird die Präfixsumme berechnet, indem die Knoten je unterschiedliche Daten zu ihren linken und rechten Knoten gesendet werden. Pipelining wird wie bei Reduktion und Broadcast angewendet.<br /> <br /> Auf einem Binärbaum ist Präfixsumme in Zeit &lt;math&gt; \mathcal{O}(\alpha \log p + \beta n) &lt;/math&gt; möglich.<br /> <br /> {{clear}}<br /> <br /> == Barriere &lt;ref name=&quot;:6&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 408&lt;/ref&gt;==<br /> <br /> Die Barriere ist eine Verallgemeinerung des Konzepts der Barriere auf verteiltes Rechnen. Wenn eine Prozessoreinheit die Barriere aufruft, dann wartet sie, bis alle anderen Prozessoreinheiten ebenfalls Barriere aufgerufen haben, before sie im Programm fortfährt. Die Barriere ist also eine Möglichkeit der globalen [[Prozesssynchronisation|Synchronisation]].<br /> <br /> Eine Möglichkeit, die Barriere zu implementieren ist es, All-reduce ({{section link||All-reduce}}) mit einem leeren Operanden aufzurufen. Dadurch wird die Nachrichtengröße &lt;math&gt;n&lt;/math&gt; auf einen konstanten Faktor reduziert und nur der Latenz-Term in der Laufzeitbetrachtung bleibt übrig. Da die Laufzeit für All-reduce &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; ist, liegt die Laufzeit der Barriere also in &lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;.<br /> <br /> == Gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. A dotted line connects the high left square with the high right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in the high right rectangle in a row.|thumb|Information flow of Gather operation performed on three nodes.]]<br /> <br /> Das Muster Gather wird genutzt, um Daten von allen Prozessoreinheiten zu sammeln und auf einer einzelnen Prozessoreinheit zusammenzuführen. Liegt zu Beginn die Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, so soll nach dem Gather auf der Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; gespeichert werden. Konzeptionell entspricht Gather der Reduktion ({{section link||Reduktion}}) wobei der Operator die [[Konkatenation_(Listen)|Konkatenation]] der Nachrichten ist. Konkatenation ist assoziativ und erfüllt damit die Voraussetzung der Reduktion.<br /> <br /> Durch die Nutzung des Binomialbaum-Algorithmus der Reduktion wird eine Laufzeit von &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; erreicht.<br /> Die Laufzeit ist ähnlich zur Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt; see Reduktion, bis auf einen zusätzlichen Faktor &lt;math&gt; p &lt;/math&gt; der an den Term &lt;math&gt; \beta n &lt;/math&gt; multipliziert wurde. Dieser Faktor kommt daher, dass die Größe der Nachrichten in jedem Schritt zunimmt. Dies ist durch die Konkatenation als Operator bedingt und steht im Gegensatz zu Operatoren wie &lt;math&gt; min &lt;/math&gt;, die eine konstante Nachrichtengröße über alle Schritte bedingen.<br /> <br /> {{clear}}<br /> <br /> == All-gather &lt;ref name=&quot;:7&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 412-413&lt;/ref&gt;==<br /> <br /> [[File:All-Gather.png|alt=There are three squares vertically aligned on the left and three rectangles vertically aligned on the right. Three dotted lines connect the high left square with the high right rectangle, the mid left square with the mid right rectangle and the low left square with the low right rectangle. Two solid lines connect the mid and low left squares with the high right rectangle. Two solid lines connect the high and low left squares with the mid right rectangle. Two solid lines connect the high and mid left squares with the low right rectangle. The letters a, b and c are written in the left squares from high to low. The letters a, b and c are written in all right rectangles in a row.|thumb|Information flow of All-Gather operation performed on three nodes.]]<br /> <br /> Das Muster All-gather wird genutzt, um Daten aller Prozessoreinheiten auf allen Prozessoreinheiten zu sammeln. Gegeben Nachricht &lt;math&gt; m_i &lt;/math&gt; auf Prozessoreinheit &lt;math&gt; p_i &lt;/math&gt;, soll die Nachricht &lt;math&gt;m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; auf alle Prozessoreinheiten transferiert werden.<br /> <br /> All-gather kann auf verschiedene Arten betrachtet werden. Einerseits entspricht es dem Muster All-reduce mit der Operation Konkatenation, so wie Gather als Reduce mit Konkatenation gesehen werden kann. Andererseits entspricht es dem Muster Gather mit anschließendem Broadcast der aggregierten Nachricht mit Größe &lt;math&gt;pn&lt;/math&gt;. Wir sehen, dass All-gather in Laufzeit &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt; durchgeführt werden kann.<br /> <br /> {{clear}}<br /> <br /> == Scatter &lt;ref name=&quot;:8&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 413&lt;/ref&gt;==<br /> <br /> [[File:Scatter.png|alt=There are three rectangles vertically aligned on the left and three squares vertically aligned on the right. A dotted line connects the high left rectangle with the high right square. Two solid lines connect the high left rectangle with the mid and low right squares. The letters c, b and a are written in the high left rectangle in a row. The letters a, b and c are written in the right right squares from high to low.|thumb|Information flow of Scatter operation performed on three nodes.]]<br /> <br /> Das Muster Scatter wird eingesetzt, um Daten einer Prozessoreinheit auf alle Prozessoreinheiten aufzuteilen. Es unterscheidet sich vom Broadcast insofern, als dass nicht alle Prozessoreinheiten die gleiche Nachricht erhalten. Stattdessen erhält jede Prozessoreinheit einen Ausschnitt. Es soll also die auf der Wurzel vorliegende Nachricht &lt;math&gt;m = m_1 \cdot m_2 \cdot \ldots \cdot m_p&lt;/math&gt; so verteilt werden, dass anschließend auf Prozessoreinheit &lt;math&gt;p_i&lt;/math&gt; die Nachricht &lt;math&gt;m_i&lt;/math&gt; vorliegt. Scatter kann als invertierter Gather gesehen werden.<br /> <br /> Für Scatter lassen sich die gleichen Überlegungen wie für Gather anstellen. Das Resultat ist eine Laufzeit in &lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;.<br /> <br /> {{clear}}<br /> <br /> == All-to-all &lt;ref name=&quot;:9&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, pp. 413-418&lt;/ref&gt;==<br /> <br /> Das Muster All-to-all stellt das allgemeinste Kommunikationsmuster dar. Für &lt;math&gt;0 \leq i &lt; p, 0 \leq j &lt; p&lt;/math&gt; ist &lt;math&gt;m_{i, j}&lt;/math&gt; die Nachricht, die zu Beginn auf Prozessoreinheit &lt;math&gt;i&lt;/math&gt; vorliegt und nach der Operation auf Prozessoreinheit &lt;math&gt;j&lt;/math&gt; liegt. Es hat also jede Prozessoreinheit individuelle Nachrichten für alle anderen Prozessoreinheiten. Alle anderen Muster die keine Operation benötigen lassen sich durch All-to-all ausdrücken. Beispielsweise kann Broadcast emuliert werden, bei dem die Wurzel &lt;math&gt;r = p_i&lt;/math&gt; die Nachricht &lt;math&gt;m&lt;/math&gt; verteilt emuliert werden, indem &lt;math&gt;m_{i, j} = m&lt;/math&gt; gesetzt wird und &lt;math&gt;m_{k, j}&lt;/math&gt; leere Nachricht für &lt;math&gt;k \neq i&lt;/math&gt;.<br /> <br /> Sofern das Netzwerk als [[Vollst%C3%A4ndiger_Graph|vollständiger Graph]] gesehen werden kann, ist eine Laufzeit in &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt; möglich. Dabei wird All-to-all durch &lt;math&gt; p - 1 &lt;/math&gt; Runden paarweisen Nachrichtenaustauschs implementiert. Falls &lt;math&gt; p &lt;/math&gt; eine Zweierpotenz ist, kann dazu in Runde &lt;math&gt; k &lt;/math&gt; Knoten &lt;math&gt; p_i &lt;/math&gt; mit Knoten &lt;math&gt; p_j, j= i \oplus k&lt;/math&gt; kommunizieren.<br /> <br /> Falls die Nachrichtengröße klein ist und die Latenz die Laufzeit dominiert, kann durch einen Hyperwürfel eine Laufzeit in &lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; erreicht werden.<br /> <br /> [[File:All-to-All.png|alt=There are three rectangles vertically aligned on the left and three rectangles vertically aligned on the right. The rectangles are three time higher as wide. The terms a1, a2 and a3 are written in the high left rectangle one below the other. The terms b1, b2 and b3 are written in the mid left rectangle one below the other. The terms c1, c2 and c3 are written in the low left rectangle one below the other. The terms a1, b1 and c1 are written in the high right rectangle one below the other. The terms a2, b2 and c2 are written in the mid right rectangle one below the other. The terms a3, b3 and c3 are written in the low right rectangle one below the other. A dotted line connects a1 from the high left rectangle and a1 from the high right rectangle. A dotted line connects b2 from the mid left rectangle and b2 from the mid right rectangle. A dotted line connects c3 from the low left rectangle and c3 from the low right rectangle. Solid lines connect the other corresponding terms between the left and right rectangles.|thumb|Information flow of All-to-All operation performed on three nodes. Letters indicate nodes and numbers indicate information items.]]<br /> <br /> {{clear}}<br /> <br /> == Laufzeitüberblick &lt;ref name=&quot;:10&quot;&gt;Sanders, Mehlhorn, Dietzfelbinger, Dementiev 2019, p. 394&lt;/ref&gt;==<br /> Diese Tabelle gibt einen Überblick über die bestmöglichen asymptotischen Laufzeiten, sofern die Wahl der [[Topologie_(Rechnernetz)|Netzwerktopologie]] frei ist.<br /> <br /> Beispieltopologien für eine optimale Laufzeit sind je nach Algorithmus Binärbaum, Binomialbaum und Hyperwürfel.<br /> <br /> In der Praxis müssen die Algorithmen an die tatsächlich verfügbaren Topologien angepasst werden, beispielsweise [[Fat_Tree|Fat tree]], Gitter, Dragonfly.<br /> <br /> Bei einigen Operationen kann die Wahl des optimalen Algorithmus von der Eingabegröße &lt;math&gt;n&lt;/math&gt; abhängen. Beispielsweise ist Broadcast für kurze Nachrichten optimal auf einem Binomialbaum während für lange Nachrichten Kommunikation die Pipelining verwendet auf einem Binärbaum optimal ist.<br /> <br /> In der Tabelle steht in der Spalte ''Name'' der Name des jeweiligen Musters. Die Spalte ''# Sender'' listet die Anzahl Prozessoreinheiten, die initial eine zu verteilende Nachricht haben. ''# Empfänger'' listet die Anzahl Knoten die eine Nachricht zu empfangen haben. ''# Nachrichten'' zeigt die Anzahl Nachrichten, die insgesamt auszuliefern sind. ''Berechnung'' listet, ob zusätzlich zur Kommunikation noch eine Berechnung stattfindet. ''Laufzeitkomplexität'' listet die asymptotische Laufzeit einer optimalen Implementierung unter freier Wahl der Topologie.<br /> {| class=&quot;wikitable&quot;<br /> |+<br /> !Name<br /> !# Sender<br /> !# Empfänger<br /> !# Nachrichten<br /> !Berechnung<br /> !Laufzeitkomplexität<br /> |-<br /> |Broadcast<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Reduktion<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |All-reduce<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Präfixsumme/ Scan<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |ja<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta n)&lt;/math&gt;<br /> |-<br /> |Barriere<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;0&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p)&lt;/math&gt;<br /> |-<br /> |Gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-gather<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |Scatter<br /> |&lt;math&gt;1&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\alpha \log p + \beta p n)&lt;/math&gt;<br /> |-<br /> |All-to-all<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p&lt;/math&gt;<br /> |&lt;math&gt;p^2&lt;/math&gt;<br /> |nein<br /> |&lt;math&gt;\mathcal{O}(\log p (\alpha + \beta p n))&lt;/math&gt; oder &lt;math&gt;\mathcal{O}(p (\alpha + \beta n))&lt;/math&gt;<br /> |}<br /> <br /> == References ==<br /> {{cite book|last1=Sanders|first1=Peter|title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox|last2=Mehlhorn|first2=Kurt|last3=Dietzfelbinger|first3=Martin|last4=Dementiev|first4=Roman|date=2019|publisher=Springer Nature Switzerland AG|isbn=978-3-030-25208-3|authorlink1=Peter Sanders (computer scientist)|authorlink2=Kurt Mehlhorn}}</div> RenderFlamingo