Parallele Algorithmen auf Gittern und Hypercubes Vorwort Diese Mitschrift entstand nach der gleihnamigen Vorlesung von Prof. Manfred Kunde im Sommersemester 2007 an der TU Ilmenau. 3 Inhaltsverzeichnis Vorwort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Inhaltsverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Phase 1 . . . . . . . . . . . . . . . . . . Phase 2 . . . . . . . . . . . . . . . . . . 1.1 Komplexitätsmaße: Bits gegen Wörter . . . . Pipelining (systolischer Sortierer) . . 1.2 Untere Schranken . . . . . . . . . . . . . . . . . . 1.2.1 E/A-Bandbreite . . . . . . . . . . . . . . . 1.2.2 Durchmesser eines Netzwerkes . . . . . . 1.2.3 Bisektionsweite . . . . . . . . . . . . . . . . 1.3 Eigenschaften des Berechnungsmodells . . . . 1.3.1 Eigenschaften des Prozessors . . . . . . . 1.4 Bewertungskriterien für parallele Algorithmen 1.4.1 Allgemeine Bewertung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Basisalgorithmen auf Bäumen und Gittern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. ... .. .. .. .. .. .. ... 2.1 Parallele Präfixberechnung . . . . . . . . . . . . . . . . . 2.1.1 Segmentierte Präfixberechnung . . . . . . . . . . . 2.1.2 Erste Anwendungen . . . . . . . . . . . . . . . . . . 2.1.2.1 Paritätsberechnung . . . . . . . . . . . . . . . 2.1.2.2 Suffixberechnung . . . . . . . . . . . . . . . . 2.1.2.3 Indexproblem . . . . . . . . . . . . . . . . . . . 2.2 Addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Addition mit Carry-Lookahead . . . . . . . . . . . 2.2.2 „Carry-Save“ Addition . . . . . . . . . . . . . . . . . 2.2.2.1 Verkürzung der Laufzeit . . . . . . . . . . . . 2.3 Multiplikation, Konvolution, Division . . . . . . . . . . 2.3.1 Faltung auf dem linearen Feld . . . . . . . . . . . 2.3.2 Multiplikation auf linearem Feld . . . . . . . . . . 2.3.3 Division . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4 Matrizenberechnung . . . . . . . . . . . . . . . . . . . . . 2.4.1 Multiplikation von Matrizen und Vektoren . . . 2.4.2 Multiplikation von Matrizen . . . . . . . . . . . . . 2.4.2.1 Lösen von dreieckigen Gleichungssystemen Ineffizienzen . . . . . . . . . . . . . . . . . . . . 2.4.2.2 Invertierung von Dreiecksmatrizen . . . . . 2.5 Graphalgorithmen . . . . . . . . . . . . . . . . . . . . . . 2.5.1 Transitive Hülle . . . . . . . . . . . . . . . . . . . . 2.5.2 Weitere Probleme . . . . . . . . . . . . . . . . . . . 2.5.2.1 Kürzeste Wege (Floyd) . . . . . . . . . . . . . 2.5.2.2 Minimale Spannbäume . . . . . . . . . . . . . 2.5.2.3 Rekurrente Gleichungssysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 8 8 8 9 9 9 10 10 10 10 10 13 . . . . . . . . . . . . . . . . . . . . . . . . . . 13 14 14 14 14 14 15 15 15 16 16 17 17 18 19 19 19 19 20 20 21 21 21 21 21 21 3 Datentransport und Sortieren auf Gittern . . . . . . . . . . . . . . . . . . . . . . . . . . 23 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 3.1 3.2 3.3 3.4 Inhaltsverzeichnis Ein Zusammenhang zwischen Routing und Sortieren . . . . Odd-Even Trasposition Sort . . . . . . . . . . . . . . . . . . . . Row-Column Sort . . . . . . . . . . . . . . . . . . . . . . . . . . Sortieren in O(n) auf n × n-Gitter . . . . . . . . . . . . . . . . 3.4.1 Ein einfaches Sortieren durch Mischen . . . . . . . . . . 3.4.2 Sortieren in 3 n + o(n) auf einem n × n-Feld . . . . . . . 3.5 Untere Schranken fürs Sortieren . . . . . . . . . . . . . . . . . 3.5.1 Das Joker-Argument . . . . . . . . . . . . . . . . . . . . . 3.5.2 Bemerkungen zum Sortieren auf n × n-Gitter . . . . . 3.6 Permutationsrouting . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.1 Greedy-Algorithmus . . . . . . . . . . . . . . . . . . . . . . 3.6.2 Randomisierte Algorithmen . . . . . . . . . . . . . . . . . 3.6.3 Deterministischer Pakettransport mit kleinen Speicher 3.6.4 Hot-Potato-Routing . . . . . . . . . . . . . . . . . . . . . . 3.7 Multi-Packet-Probleme . . . . . . . . . . . . . . . . . . . . . . . 3.7.1 Sortieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.7.2 1-1-Sortieren in Modell 2 . . . . . . . . . . . . . . . . . . . 3.7.3 h-h-Sortieren mit Hilfe des All-to-all Mappings . . . . 4 Hypercubes und verwandte Netzwerke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 23 24 25 25 26 27 27 28 28 29 29 30 30 30 31 31 31 .. .. .. .. .. ... .. .. .. .. .. .. ... 33 4.1 Der Hypercube . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Einbettung von Feldern . . . . . . . . . . . . . . . . . . . . . 4.1.2 Einbettung von vollständigen binären Bäumen . . . . . . . 4.2 Butterfly, CCC (Cube-Connected Cycles), Benes-Netzwerk . . 4.2.0.1 Butterfly . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.0.2 Wrapped-Butterfly . . . . . . . . . . . . . . . . . . . . . 4.2.1 Benes-Netzwerke . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.2 CCC - Cube-connected-cycles . . . . . . . . . . . . . . . . . . 4.2.3 Simulation beliebiger Netzwerke . . . . . . . . . . . . . . . . 4.2.3.1 Off-line Permutationsrouting auf einem a × b-Gitter 4.3 Sortieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.1 Butcher’s Odd-Even-Mergesort . . . . . . . . . . . . . . . . . 4.4 Packet-Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4.1 Der Greedy-Algorithmus . . . . . . . . . . . . . . . . . . . . . Greedy-Algorithmus . . . . . . . . . . . . . . . . . . . . . 4.4.1.1 oblivious Routing . . . . . . . . . . . . . . . . . . . . . . 4.4.2 Spezielle Routingprobleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 33 34 35 35 36 36 36 36 36 37 37 38 38 38 38 38 Kapitel 1 Einführung Die Vorlesung behandelt theoretische Aspekte des Entwurfs und der Analyse von parallelen Algorithmen. Dies betrachten wir besonders auf Netzwerken (Gitter, Hypercubes, Bäume) von Prozessoren. Dabei steht im Vordergrund, mit vielen kleinen, einfachen Prozessoren große komplizierte Aufgaben zu lösen. Dabei besteht immer das Kommunikationsproblem, d.h. ein sinnvolles Arbeiten der Prozessoren untereinander zu gewährleisten. Dabei treten einige Kernprobleme auf: • • • Organisation des Datentransports Sinnvolle Verbindung der Prozessoren Welche Netze können realisiert werden? Beispiel 1.1. Sortieren auf einem linearen Feld Definition 1.2. • • E/A nur über linken Prozessor Jeder Prozessor: ◦ • lineares Feld siehe 1. Abb eigenes lokales Kontroll-/Arbeitsprogramm ◦ lokalen Speicher ◦ Verbindungsgraph der zugrunde liegt ist fest lineares Feld ist ein einfaches Beispiel für ein Netzwerk mit fester Verbindungsstruktur (fixed-connection network) ◦ ◦ ◦ Prozessoren können nur mit physikalischen Nachbarn direkt kommunizieren E/A erfolgt auf fest vorgegebenen Prozessoren bzw. Ports lokaler Speicher sei O(1) Berechnungsschritte im Zeitinterval (t,t + 1) Jeder Prozessor: 1. erhält Eingaben (inputs) von seinen Nachbarn 2. inspeziert seinen lokalen Speicher 3. führt eine lokale Berechnung aus 4. generiert Ausgaben (outputs) für seine Nachbarn 5. bringt lokalen Speicher auf den neusten Stand (update) Die Zeit entspricht dabei einer globalen Uhr und zu jedem Zeitpunkt t befindet sich das Netz von Prozessoren in einem eindeutig definierten Zustand (synchronisiertes Arbeiten). Bei der Sortierung auf einem linearen Feld gibt es N Eingabezahlen auf einem linearen Feld der Größe N , die in 2 Phasen sortiert werden. 7 8 Einführung Phase 1 1. Nimm Eingabe von links 2. Vergleiche Eingabe mit gespeichertem Wert 3. Speichere kleineren von beiden 4. gib den größeren Wert nach rechts aus Beweis. Behauptung: In Phase 1 werden N Zahlen aufsteigend (d.h von links nach rechts) sortiert. Induktion über N : • • N = 1: trivial (ein Wert der für sich sortiert ist) N > 1: Bei N Zahlen untersucht der erste Prozessor P1 in den ersten N Schritten alle von links kommenden Werte und behält einen kleinsten. N − 1 Werte werden nach rechts weitergegeben und von den verbleibenden N − 1 Prozessoren (rechts) sortiert (nach Induktionsvoraussetzung). Phase 2 Ausgabe der Daten über linken Prozessor. Dabei ist kein Broadcast erwünscht, sondern nur lokale Kontrolle. Möglichkeiten: 1. Jeder Prozessor kennt seine Position i und erhält einen Zähler. Nachdem er N + 1 − i Eingaben gesehen hat, beginnt Pi mit den Ausgaben seines Wertes nach links. Anschließend gibt er von rechts kommende Werte nach links. Benötigt 3 N − 1 Schritte. 2. Der am weitesten rechts stehende Prozessor PN beginnt seinen Wert nach links zu senden, unmittelbar nachdem er ihn erhalten hat. Alle anderen geben Werte nach links, wenn sie welche von rechts erhalten haben. Insgesamt 4 N − 2 Schritte. 3. Jeder Prozessor, der keine Eingabe von links mehr erhält, beginnt seinen Wert nach links zu senden. Akzeptiert danach Werte von rechts und gibt sie nach links weiter. Der links stehende Prozessor erhält nach jedem zweiten Schritt eine Ausgabe von rechts, d.h. die Phasen überlappen sich. Insgesamt 3 N − 1 Schritte. Dieses Verfahren ist sehr einfach (kein Zähler, keine komplizierte Kontrolle). Es können mit diesem Verfahren auch Sortierung von weniger als N Elementen vorgenommen werden. Dieses Schema ist ähnlich zu „Zero-Time-Sorter“ von IBM. 1.1 Komplexitätsmaße: Bits gegen Wörter Sortieren auf linearem Feld → Wortmodell. Ein Schritt wird dabei für Vergleich und Transport ganzer Wörter (Zahlen). Beim Bitmodell (logarithmische Kosten) zählen wir die Anzahl der Bitoperationen. Wenn wir nun das Bitmodell auf unserer Sortierung anwenden, werden die Eingabezahlen durch k Bits dargestellt. Dabei müssen wir bei den Vergleichen jeweils das signifikante Bit bestimmen, um zu wissen, welche der beiden Zahlen größer ist. Insgesamt kostet der Vergleich bei k Bit O(k) und sogar Ω(k). Insgesamt ist der Aufwand also Ω(k · N ) Bitschritte für das Sortieren. In Abbildung 2 sehen wir eine beschleunigte Version. Dadurch können wir in O(log k) Schritten, die Entscheidung treffen. Der Gesamtaufwand beträgt dann damit O(log k) Bitschritte für den Vergleich zweier k-Bitwörter und für den Sortierer damit O(N · log k). Die genutzte Struktur nennt man lineares Feld von vollständigen binären Bäumen (siehe Abbildung 3). Die Frage steht nun, ob es noch schneller geht. Pipelining (systolischer Sortierer) Ein Bitvergleicher mit folgendem Zeitverhalten: 9 1.2 Untere Schranken Zeit t während (t + 1) Zeit t + 1 Eingabe Berechnung Ausgabe Tabelle 1.1. Das genaue Schaltverhalten ist dabei in Abbildung 4 zu sehen. Die Arbeitsweise lässt sich am Besten am Beispiel demonstrieren mit folgendem Szenario: • nur 1 Wortprozessor mit k Zellen • Eingabe von links mit verdrehter Bitfolge (stewed input ) • kleinsten Wert von N Zahlen berechnen Dazu ist das Folienbeispiel vom 12.04.2007 Figure 1-8 zur Anschauung empfohlen. Der Beweis der Korrektheit ist schwierig, deswegen hier nur ein paar Fakten: • Nach Schritt i (d.h. Zeitintervall (i − 1, i)) ◦ ◦ 1≤i≤N +k −1 enthält Zelle j, 1 ≤ j ≤ k und j ≤ i, das j-te Bit der kleinsten Zahl unter den ersten Eingaben. ◦ min (i − j + 1, N ) Kosten für Minimum N + k − 1 Schritte. Beobachtung. • • minimaler Wert bleibt in Zellen des ersten Prozessors restlichen Werte verlassen den Prozessor als Ausgabe (rechts) - verdreht und in permutierter Reihenfolge. Sortieren. N k-Zellen-Prozessoren k × N Feld (Abbildung in Foliensätzen 12.4.07). Die Kosten dafür sind: • Phase 1: N + k − 1 + N − 1 = 2 · N + k − 2 • Total: 3 · N + k • Phase 2: Wie im Wortmodell Wir sind damit in O(n + k) Bitoperationen. Können wir dies noch weiter verbessern? 1.2 Untere Schranken 1.2.1 E/A-Bandbreite Beispiel 1.3. k Eingabedrähte für den E/A-Prozessor. Insgesamt werden N · k Bit eingegeben, d.h. wir benötigen N Bitschritte ⇒ Ω(N ). 1.2.2 Durchmesser eines Netzwerkes Definition 1.4. Durchmesser(G) = maxu,v ∈V d(u, v) Dabei ist d(u, v) der minimale Abstand von u und v. Die Distanzschranke für ein k × N -Feld ist also N + k − 2. 10 Einführung 1.2.3 Bisektionsweite Definition 1.5. Als Bisektionsweite eines Graphen G = (V , E) bezeichnet man die Zerlegung eines Graphen in G1 = (V1, E1) und G2 = (V2, E2) mit V1 ∪ V2 = V und V1 ∩ V2 = ∅ und E1, E2 ⊆ E , E1 ∩ E2 = ∅, wobei kV1| − |V2k ≤ 1 und Esep = E \{E1 ∪ E2} = E ∩ V1 × V2. Gesucht ist min |Esep | Beispiel 1.6. k × N -Feld Bisektionsweite (Abbildung 6): • • min (k, N ) oder min (k, N ) + 1 Beispiel 1.7. N gerade, N ≥ k N N größten Zahlen stehen in Prozessoren 1, , 2 . Dann müssen 2 kanten transportiert werden. Daraus können wir nun aber N 2 · k Bits über k Bisektions- N 2 ·k N = k 2 mindestens Ω(N ) Schritte schlussfolgern. 1.3 Eigenschaften des Berechnungsmodells Bisher haben wir explizite aber auch implizite Annahmen über unser zugrundeliegendes Berechnungsmodell gemacht. Für die Berechnung unterer und oberer Schranken ist eine exaktere Formulierung oft nötig. 1.3.1 Eigenschaften des Prozessors 1. Fest Eigenschaften: Prozessoren stehen unter lokaler Kontrolle, d.h. die Funktionen, die jeder einzelne Prozessor ausführen kann, hängen nur ab von: • • Inhalt des lokalen Speichers (u.a. lokalem Programm) lokalen Eingaben von benachbarten Prozessoren bzw. E/A-Ports Weiterschreiben 1.4 Bewertungskriterien für parallele Algorithmen 1.4.1 Allgemeine Bewertung Beschreibung der Leistung erfolgt durch: 1. T : Laufzeit des Algorithmus ALG 2. P : Anzahl der Prozessoren, die ALG benötigt Γ 3. S: Speedup (Beschleunigung), S = T , wobei Γ die Laufzeit eines schnellsten sequentiellen Algorithmus ist 4. W : geleistete Arbeit (work ), definiert durch W = T · P . Γ 5. E: Effizienz, definiert durch E = W . Es gilt E= Γ S Γ = = W T ·P P 11 1.4 Bewertungskriterien für parallele Algorithmen Beispiel 1.8. Linearer Sortierer • P = N , N Anzahl der zu sortierenden Elemente • S = Θ(log N ) • • • T = Θ(N ), Γ = Θ(N · log N ) W = Θ(N 2) log N E=Θ N Ziel. Speedup so groß wie nur möglich mit S = P oder S = Θ(P ). Generell gilt: S ≤ P , denn in T · P Schritten der parallele Algorithmus sequentiell simuliert Γ werden. Daher Γ ≤ T · P ⇒ S = T ≤ P . Die Laufzeit T soll so klein wie möglich und die Effizienz möglichst nahe an 1 sein. Beides zusammen nicht immer zu erreichen. Bemerkung 1.9. • • leerstehende Prozessoren und Ausführung unnützer Aufgaben sind darin enthalten manchmal andere Definition der Arbeit: N1 + N2 + + NT , Ni: Anzahl der aktiven Prozessoren im i-ten Schritt Skalierung und Granularität. • Bearbeitung von N Elementen • Typische Annahme in der Vorlesung P ≥ N • jeder Prozessor muss mindestens • Algorithmen zum Lösen in feinkörnigen Parallelrechnern ähnlich zu Ergänzen, Folien 16.04.07 Was passiert bei P < N ? l N P m Elemente speichern können Konvertierung von Algorithmen. Seien G1 und G2 2 Netzwerke identischen Typs mit P1 bzw. P2 Prozessoren. Es gelte: P2 < P1. Wir geben nun eine Methode (Algorithmus für G1 liege vor) zur Konvertierung an: l m P • Jeder Prozessor aus G2 simuliert P1 Prozessoren aus G1 2 l m P • normalerweise dabei Verlangsamung um Faktor P1 (Skalierung) 2 • Skalierung nach unten Bemerkung 1.10. Skalierung nach oben von Algorithmus G2 nach Algorithmus G2 i.A. nicht so einfach, manchmal sogar unmöglich (es gibt dafür eine eigene Komplexitätsklasse in der Komplexitätstheorie) Kapitel 2 Basisalgorithmen auf Bäumen und Gittern 2.1 Parallele Präfixberechnung Wir betrachten einen assoziativen Operator ⊗ über einer Menge X. Es gilt ⊗:X ×X →X ∀a, b, c ∈ X: a ⊗ (b ⊗ c) = (a ⊗ b) ⊗ c wobei die Eindeutigkeit von a ⊗ b ⊗ c vorausgesetzt sei. Nun sei x1, x2, , xN ∈ X. Berechne für alle i, 1 ≤ i ≤ N : yi = x1 ⊗ x2 ⊗ ⊗ xi Dies ist der i-te Präfix (als Beispiel kann man für ⊗ “ + “ nutzen). Für N Eingaben wollen wir nun alle Präfixe auf binären Bäumen mit N Blättern berechnen. Die Werte xi liegen nun am i-ten Blatt an, die Blätter seien von links nach rechts nummeriert. Der Ablauf des Algorithmus in Phase 1 wird in Abbildung 7 bzw. Foliensatz vom 16.04.07 deutlich. Die Phase 2 (die mit Phase 1 überlappt) sieht folgenderweise aus: • aus dem linken Teilbaum erhaltene Produkte werden in rechte Teilbäume geleitet (siehe Abbildung 8) Nun müssen wir noch das Programm spezifizieren. Dafür betrachten wir das Programm eines inneren Knotens (siehe Abbildung 9). 1. if phase = 1 then a. if El empty and Er empty then begin i. phase = 2 ii. A 4 El ⊗ Er iii. Ar 4 El b. else update El and Er 2. else {Phase 2} begin a. Al 4 E b. Ar 4 E Es fällt uns noch das Programm eines Blattes. 1. if phase = 1 then A = C; phase = 2; 2. else C = E ⊗ C Das ursprüngliche Einlesen ist dabei nicht berücksichtigt. Wie schnell arbeitet unser Algorithmus? Satz 2.1. Die parallele Präfixberechnung von N Elementen kann in einem binären Baum der Tiefe D und mit N Blättern in 2 D + 1 Schritten ausgeführt werden. 13 14 Basisalgorithmen auf Bäumen und Gittern Beweis. (Induktion über Tiefe D) Wir definieren kurz, dass wir in einem binären Baum mit Wurzel w den linken Teilbaum als lTb bezeichnen mit Tiefe Dl und der rechte Teilbaum als rTb mit Tiefe Dr. • • Induktionsanfang: D = 0, d.h. nur ein Blatt. 1 Schritt zum Einlesen benötigt. Annahme: Behauptung des Satzes ist schon für alle Binärbäume mit Tiefe ≤ D − 1 gilt Wegen D = max (Dl , Dr) + 1, gilt Dr , Dl ≤ D − 1. O.B.d.A. seien die Blätter des lTb ursprünglich mit Eingaben x1, , xk und rTb mit Eingaben xk+1, , xN versehen. Nach Annahme steht nach 2Dl + 1 Schritten im i-ten Blatt des lTb x1 ⊗ ⊗ xi und 2Dr + 1 Schritten im j-ten Blatt des rTb xk+1 ⊗ ⊗ xk+ j . Dabei ist Berechnung der Wurzel noch nicht berücksichtigt. In (D, D + 1) berechnet die Wurzel Produkt x1 ⊗ ⊗ xk ⊗ ⊗ xN und gibt x1 ⊗ ⊗ xk in rechten Teilbaum. Dieser Wert wird dann an alle Knoten des rTb weitergeleitet. Die vorherigen Berechnungen im Teilbaum werden davon nicht beeinflusst, da sie quasi wellenförmig davor stattgefunden haben (letzter Wert von Wurzel des rechten Teilbaums wurde schon zum Zeitpunkt Dr + 1 ≤ D weitergereicht). D.h., spätestens im Zeitintervall (2 D, 2 D + 1) erhält das j-te Blatt des rechten Teilbaums als Eingabe den Wert x1 ⊗ ⊗ xk, und es blidet mit schon vorhandenem xk+1 ⊗ ⊗ xk+ j den richtigen Wert x1 ⊗ ⊗ xk+ j . lTb mit Induktoinsannahme auch vollständig betrachtet. Folgerung 2.2. Die Präfixe von N Elementen können auf einem binärem Baum können in O(log N ) Schritten berechnet werden. Beweis. Nach Satz 2.1. und vollständigem Baum mit 2 ⌈log N ⌉ Blättern, wobei nur die linken N ≤ 2 ⌈log N ⌉ Blätter belegt sind (restlichen mit neutralem Element bzw. ⊗ ). 2.1.1 Segmentierte Präfixberechnung Diese stellen eine Folge von Präfixberechnungen auf unterschiedlichen Datenmengen mit gleichen Operator dar. Beispiel 2.3. Sei ⊗ = + , berechne den Präfix der Folge (2, 3), (1, 7, 2), (1, 3, 6). (siehe Abbildung 10). 2.1.2 Erste Anwendungen 2.1.2.1 Paritätsberechnung b = bNbN −1, , b0 ∈ {0, 1}N +1 mit parity(b)= 0 falls Anzahl der Einsen gerade 1 sonst • parity(0) = 0 • ⊗ - XOR oder Addition modulo 2, später ⊕ . • . Es gilt: parity(1) = 1 Mit partieller Präfixberechnung sämtliche Paritäten aller Präfixe parity(b0 bi) bei Belegung b0, b1, , bN . Paritäten aller Suffixe parity(bNbN −1 bj ) bei Belegungen bN , bN −1, , b0. 2.1.2.2 Suffixberechnung Gegeben sei x1, , xN . Berechne alle Suffixe, d.h. xi ⊗ ⊗ xN , i = 1, , N . Wir können diese Struktur als Präfix mit Eingabe xN , , x1 und neuem Operator ⊗∼ mit a ⊗∼ b = b ⊗ a. Man kann es auch direkt mit einem geänderten Programm mittels x1, , xn berechnen. 2.1.2.3 Indexproblem Eine weitere Anwendung sind Indexprobleme. Dabei gibt es eine Liste von Prozessoren Proz1, , ProzN , die ein Datenpaket enthalten oder nicht. Die Frage ist nun, wie der Index des Paketes in Proz j (von links nach rechts gelesen) (Abbildung 11). 15 2.2 Addition 2.2 Addition 2.2.1 Addition mit Carry-Lookahead x, y ∈ N0 sei gegeben. Die Aufgabe besteht nun darin, x + y = z zu bestimmen. Sequentiell kann es in wie Abbildung 12 betrachtet werden. Der Übertrag scheint dabei sequentiell einzugehen. Beispiel 2.4. zur Vereinfachung ist das erste und letzte Bit 0. ⊕ Sei die Addition modulo 2. xi yi xi ⊕ yi ⊕ ci−1 ci li (siehe Möglichkeiten unten) ui (siehe Notierung 2.5) vi (Übertragsbit) 0 0 1 0 S G 1 1 0 0 1 P G 1 1 1 1 1 G G 1 1 1 1 1 G G 1 0 1 0 1 P G 1 0 1 0 1 P G 1 1 0 0 1 P G 1 1 1 0 1 G S 0 0 0 0 0 S S 0 1 0 1 0 P S 0 0 1 1 0 P S 0 0 0 1 0 S G 1 1 1 0 1 G S 0 0 0 0 0 S S 0 Tabelle 2.1. Notierung 2.5. Man kann lokal an den einzelnen Bitpositionen etwas sehen: • 3 verschiedene Möglichkeiten des Übertrages: (S) Jedes Paar von Bits {0, 0} stoppt einen eventuell hereinkommenden Übertrag (P) Jedes Paar von Bits {0, 1} reicht einen hereinkommenden Übertrag weiter (G) Jedes Paar von Bits {1, 1} erzeugt einen Übertrag und reicht Übertrag weiter Tabelle 2.2. • Berechnung des i-ten Übertrages: ◦ ci = 1 ⇔ xi = yi = 1(G) oder die Subaddition xi + yi = 1, d.h. P und das am weitesten links stehende Lookaheadzeichen ( G) nach einer Folge (nach rechts) von P’s ist ein G. ◦ ui = li−1 ⊗ ⊗ l0 ⊗ s bzw. ui = li−1 ⊗ ui−1 ◦ zi = (xi ⊕ yi) ⊕ vi ⊗ S S S P S G G P S P G G S G G Tabelle 2.3. Satz 2.6. Die Addition zweier N-Bit langer Zahlen, kann auf einem vollständigem binären Baum mit 2 ⌈log N ⌉ Blättern mit O(log N ) Bitoperationen ausgeführt werden. 2.2.2 „Carry-Save“ Addition Es seinen nun mehrere Zahlen gegeben und das Problem besteht darin, diese N Zahlen aufzusummieren. Die N Zahlen haben jeweils k Bit. Wir gehen wie folgt vor: • Addiere N 2 Paare von k-Bitzahlen in ca. 2 log k Bitschritten. • Addiere N 4 Paare von (k + 1)-Bitzahlen in ca. 2 log (k + 1) Bitschritten. • • Addiere 1 Paar von (k + log N − 1)-Bitzahlen in ca. 2 log(k + log N − 1) Bitschritten. 16 Basisalgorithmen auf Bäumen und Gittern Die Kosten ergeben sich einfach zu ungefähr (2 · log(k + log N )) · log N und dies können wir mittels Θ(log k · log N + log log N · log N ). Unsere genutzte Architektur ist dabei ein binärer Baum mit N (k + log N ) Blättern bei Speicher O(1). Diese Laufzeit wollen wir noch weiter verbessern. 2.2.2.1 Verkürzung der Laufzeit Dies erreichen wir durch einen Trick, die „Carry-Save“-Addition. Dabei wird das Problem der Addition reduziert • von 3 Zahlen der Länge k Bit auf die Addition von 2 Zahlen der Länge k + 1 Bits. Sei folgendes gegeben: • x = xk xk−1 x1 • z = zk z1 • y = yk yk−1 y1 Sei ci di die Binärdarstellung der Summe xi + yi + zi. Wir können dies auch anders betrachten: 2 ci + di = xi + yi + zi Sei d = dk d1 und c = ck c10. Dann gilt: x+y+z= k X i=1 (xi + yi + zi) · 2i−1 = k X i=1 (2 · ci + di) · 2i−1 = k X i=1 ci · 2 i + k X i=1 di · 2i−1 = c + d Bei N mit insgesamt 0 ≡ N (mod 3) 2 N Tripel werden zu 3 N (k+1)-Bitzahlen 3 2 1 N −1 Tripel werden zu 3 N + 3 (k + 1)-Bitzahlen 3 2 2 N −2 Tripel werden zu 3 · N + 3 (k + 1)-Bitzahlen 3 1 ≡ N (mod 3) 2 ≡ N (mod 3) Tabelle 2.4. Wiederhole diese Reduktion zum 2.-ten Mal, dann gilt: 2 2 2 2 höchstens 3 ( 3 N + 3 ) + 3 (k + 2)-Bitzahlen j Pj 2 i 2 Nach j-maligem Anwenden höchstens · N + (k + j)-Bitzahlen. Diese Abschäti=1 3 3 • zung ist nun aber ≤ 2 3 j · N + 2. Was haben wir nun davon? log 3 ·N 2 2 ·N +2= Nach j = log 3 N Schritten bleiben noch maximal 3 2 1 N · N + 2 = 3 (k + log N )-Bitzahlen übrig. Nach log 3 N + 1 Schritten verbleibt noch die Addition zweier Zahlen mit 2 maximal (k + log N ) Bit Länge. 2 Zahlen mit maximal (k + log N ) Bits können wir mit der „Carry-Lookahead“-Methode mit weiterhin ca. 2 · log(k + log N ) Bitschritten. Die Reduktion von 3 auf 2 Summanden kostet lokal auf Bitebene jeweils in einem Bitschritt möglich (bei einer entsprechenden Architektur). Die Gesamtkosten summieren sich damit zu 2 · log(k + log N ) + log 3 N + 2 = O(log k + log N ) 2 Die praktische Umsetzung erfolgt mittels Wallace-Trees (siehe Abbildung 13). 2.3 Multiplikation, Konvolution, Division Gegeben seien α, b ∈ Z mit jeweils N Bits. Dabei sei a = aN aN −1 a1 und b = bN bN −1 b1 und ai , bi ∈ {0, 1}. Wir wollen nun p = a · b berechnen. Bemerkung 2.7. 1. Mit Carry-Save-Addition geht es mit O(log N ) Schritten auf Wallace-Tree und vollständigen Binärbaum mit Ω(N 2) Prozessoren. 2.3 Multiplikation, Konvolution, Division 17 2. Auf vollständigen binären Bäumen für p = a · b mindestens Θ(N ) Schritte, bei gewünschten O(N ) Prozessoren (Blättern). Dieses Ergebnis versuchen wir durch Multiplikation auf linearem Feld zu verbessern. Bemerkung 2.8. P 1. yk = i+ j=k+ j ai · b j Faltung (Konvolution) von A = (aN , , a1) und B = (bN , , b1). • Y = A × B , Y = (y2N −1, , y1) und yk ist wie in Bemerkung 2.8 mit 1 ≤ k ≤ 2 N − 1 Beispiel 2.9. Multiplikation von Polynomen (a1 + a2 x + + aN xN −1) · (b1 + b2 · x + + bN · xN −1) = y1 + y2 x + + y2N −1x2N −2. 2.3.1 Faltung auf dem linearen Feld Eine genauere Darstellung findet sich in den Folien vom 26.04.07. Formal betrachtet ergibt sich: • • Positionen: − 2 · N + 2 bis 4 · N Anfangsbelegung: ◦ t=0 − − pos0(bj ) = 4 · N + 2 − 2 · j , 1 ≤ j ≤ N − Prozessor 2 · N − k + 1 berechnet yk − ◦ ◦ pos0(ai) = − 2(i − 1), 1 ≤ i ≤ N t>0 − 2 · N Prozessoren auf Position 1, , 2 · N post(ai) = pos0(ai) + t = − 2(i − 1) + t − post(bj ) = pos0(b j ) − t = 4 · N + 2 − 2 j − t − pos2N +i− j (ai) = − 2(i − 1) + 2 · N + i − j = 2 N + 2 − i − j = 2 N − k + 1 Sei t = 2 · N + i − j (und i + j = k + 1) − pos2N +i− j (b j ) = 4 N + 2 − 2 j − 2 N − i + j = 2 N + 2 − i − j = 2 N − k + 1 letzte Treffen von Koordinaten von A und B findet zwischen aN und b1 statt, zur Zeit 2 · N +N −1=3·N −1 P Bis dahin hat jeder Prozessor 2 N + 1 − k die Summe yk = i+j =k+1 ai b j berechnet. • 2.3.2 Multiplikation auf linearem Feld Der Trick dabei ist es, die Überträge mitzuführen, wann immer auf Summe yk etwas aufaddiert wir (eigentlich: yk(t) = yk(t − 1) + ai · b j ). Statt yk(t) wird nur das letzte Bit von yk(t) gehalten: pk(t). Wann immer ai und bj zur Berechnung hineinkommen, wird ein Übertrag mitgeführt und miteinbezogen. pk(t) = lsb(pk(t − 1) + ai bj + c j (t − 1)) c j (t) = msb(pk(t − 1) + ai b j + c j (t − 1)) ai wird nach rechts gegeben und (bj , c j ) werden nach links gereicht. Die Anfangsbedingung ist analog zur Faltung und statt b j vorher, wird jetzt (bj , c j ) benutzt mit c j = c j (0) = 0 und pk(0) = 0 (siehe Folien 26.04.07). Die Berechnungen in einem Prozessor laufen wie folgt ab: 1. Prozessor erhält Eingabe nur von links (ai′s) reicht Eingabe nach rechts, keine Änderung des inneren Status 18 Basisalgorithmen auf Bäumen und Gittern 2. Prozessor erhält Eingaben von beiden Seiten ⇒ Berechnug wie erklärt 3. Prozessor erhält Eingabe nur von rechts ((b j , c j )) ⇒ arbeitet wie in Fall 2 und Eingabe 0 von links reicht keinen Wert nach rechts weiter 4. Falls Prozessor zweimal hintereinander keine Werte von rechts erhält ⇒ Stop der Berechnung. Satz 2.10. Der Zeitaufwand beträgt ≤ 4 N − 1 Schritte, da Paar (b1, c1) anfangs an Position 4 · N und letzte Berechnung in Position 1 stattfindet. Mit Fall 4 benötigen wir noch 2 Schritte mehr um zu stoppen ⇒ 4 · N + 1. Wie gut ist dieser Wert nun? Bemerkung 2.11. Wir haben 2 · N Prozessoren und 2 · N − 1 ist die untere Schranke. Der Wert ist für die vorgegebene Struktur also gut. Es lässt sich jedoch beobachten, dass nur jeder zweiter Prozessor beschäftigt ist in einem Schritt ⇒ Ineffizienz . Kann man diese Ineffizienz vermeiden? Bemerkung 2.12. (Steigerung der Effizienz) 1. Fasse 2 Prozessoren zu einem mächtigeren Prozessor zusammen. a. Abbildung 14a). Neuer Prozessor braucht nur einmal Hardware für inner-product step. b. Abbildung 14b). Vorteil: Nur ein E/A-Prozessor Auch für verschiedene Eingabegrößen nutzbar und besser geeignet. 2. Zwei Multiplikationen p = a · b und p ′ = a ′ · b ′ überlappt lösen. Die ai′ und (bj′ , c j′ ) in die Lücken der bisherigen Eingabe. [Im Prozessor: Wechselende Berechnung muss ausgeführt werden, z.b. mit Switch-Bit]. 2.3.3 Division z Gegeben seien z , y ∈ Z und wir wollen die führenden N Bit von y berechnen. Die Methode ist 1 dann y · z zu berechnen, da wir die Multiplikation schon berechnen können. Wir müssen also aus 1 1 y noch y berechnen. Dann ist für f (x) = 1 − x y, x = y eine Nullstelle. Dieses Problem der Nullstellenbestimmung können wir mittels Newton-Approximation bestimmen (siehe Folien 1 26.04.07). Sei y mit 2 ≤ y < 1 (Reskalierung falls y davon verschieden). Als erste Näherung 3 nutzen wir x0 = 2 (entspricht binär 1.1). Es gilt: 1 − xi ≤ 2−2i , ∀i, i ≥ 0 y Gna, vom Sbeyer hier noch etwas einfügen Der Beweis kann mittels vollständiger Induktion erfolgen. Zur Berechnung der xi betrachten wir nur die ersten N + 1 Bits. Wir wollen eine Approximation bis 1 |εi | = − xi y ≤ 2−(N +1) 2i ≥ N + 1 i ≥ log(N + 1) Da eine Multiplikation und Subtraktion von N -Bitzahlen auf einem linearen Feld in O(N ) geht, haben wir O(N log N ) Schritte. 19 2.4 Matrizenberechnung Das reicht uns nicht, daher wenden wir einen weiteren Trick an: Bei der Berechnung der xi reicht es, die 2i+1 + 1 führenden Bits zu berechnen (Beweis im Leighton, Seite 58). Subtraktion und Multiplikation für xi auf einem Feld der Länge O(2i) sind also in O(2i) Schritten möglich, d.h. N O 20 + 21 + + 2log N = O 1 + 2 + + + N 2 = O(2 N ) = O(N ) Schritte werden für die Multiplikation insgesamt benötigt. Mit der entsprechenden Architektur (hufeisenartig, wie schon in A12b), werden nur die ersten 2i + 1 Zellen benutzt. 2.4 Matrizenberechnung 2.4.1 Multiplikation von Matrizen und Vektoren Siehe Folie „Multiplikation von Matrix und Vektor“ vom 30.4.07 und A13. Das Programm jedes Prozessors tut folgendes innerhalb eines Zeitintervalls von t bis t + 1. 1. Setze y 4 0 2. Lese a von oben. 3. Lese x von links. 4. Berechne y 4 y + a x „inner product step“ 5. Gebe x nach rechts weiter. 6. Speichere y. Beobachtung: xi und ai, j haben im Schritt i + j − 1 den Prozessor i erreicht und yi ist nach N + i − 1 Schritten berechnet. Auf einen formalen Beweis wird verzichtet. Es werden 2 N − 1 Wortschritte benötigt. Die Gesamtlaufzeit beträgt also O(N ). 2.4.2 Multiplikation von Matrizen P Seien A, B (N , N )-Matrizen. Wir suchen C = A · B mit C = (ci, j ) und ci,j = N k=1 ai,k bk,j . Wir verwenden zur parallelen Berechnung ein (N × N )-Feld. Siehe Folie mit linearem Feld als Bild. Entspricht eigentlich dem Verfahren von oben. [Definition Gitter: Prozessor (i, j) und (k, l) sind verbunden, gdw. |i − k| + |j − l| = 1] ci,j wird in Prozessor (j , i) berechnet. Die Werte ai,k und bk,j erreichen den Prozessor (j , i) im Schritt i + j + k − 2, d.h. N X ai,k bk,j = ci, j k=1 ist nach i + j + N − 2 Schritten berechnet. Aufwand: 3 N − 2 Schritte. Die sequentielle Schulmethode hat dagegen von Γ0 = O N 3 . Dadurch ergibt 3 eine Laufzeit Γ N sich ein linearer Speedup von S0 = T0 = O N = O N 2 = O(P ), d.h. in der Anzahl der Prozessoren. Allerdings gibt es bessere sequentielle Algorithmen zur Matrizenmultiplikation. 2.4.2.1 Lösen von dreieckigen Gleichungssystemen b1 Gegeben A = (ai, j ) untere (N , N )-Dreiecksmatrix und B = bN Vektor mit ai , bj ∈ Q. Finde X mit A · X = B. Die Berechnung der Determinante einer Dreieck beschränkt sich auf das Produkt aller Elemente der Hauptdiagonale. 20 Basisalgorithmen auf Bäumen und Gittern Wir nehmen an, X existiere, d.h. es handele sich um eine reguläre Matrix A, was genau dann der Fall ist, wenn alle Elemente der Hauptdiagonale 0 ist. Folie zu Dreiecks-Gleichungssystem. Vorgehen: Berechne x1, dann x2, dann x3, usw. Bei der parallelen Berechnung berechne die Zwischenwerte ti mit t1 = b1 ti = bi − Da bi = Pi j=1 i−1 X ai, j x j j =1 ai, j x j gilt, ist ti = ai,i xi und xi = ∀i ∈ {2, , N } ti . ai,i Die ti können erst endgültig berechnen werden, wenn die entsprechenden x1, x2, , xi−1 bekannt sind. Die Berechnung der ti startet mit bekanntem x1, dann mit bekanntem x2 usw. Siehe Folie vom 30.4.2007. Ergänzend zum Bild folgende Notizen: • x j : von links nach rechts; werden in der runden Zelle berechnet, wandern dann nach rechts • ai,j : von oben nach unten; k-te Diagonale erreicht die Zelle k im Schritt k (mit k = i − j + 1, i ≥ j). • ti: von rechts nach links; Anfangswert ti 4 bi. In den viereckigen Zellen wird in einem Schritt jeweils ti 4 ti − ai,j x j aus den hereinkommenden Werten x j , ai,j , ti berechnet. t Die runde Zelle dividiert xi 4 a i , d.h. dort werden die xi erzeugt. i,i Wortschritte umfassen Multiplikation und Addition in einer viereckigen Zelle und die Division in einer runden Zelle. Wichtig ist also eine schnelle Division. Satz 2.13. Die Lösung eines unteren Dreieckssystems von N linearen Gleichungen mit N Unbekannten kann auf einem linearen Feld von N Prozessoren in 2 N − 1 Schritten ausgeführt werden. Ineffizienzen Zu jedem Schritt sind ca. die Hälfte der Prozessoren leer. Eine Verbesserung dafür wäre: • • 2 Gleichungssysteme in 2 · N Schritten bearbeiten (in Position „O“ neue Daten) oder N 1 Gleichungssystem auf 2 Prozessoren bearbeiten in 2 · N − 1 Schritten. 2 Prozessoren werden zu einem neuen Prozessor zusammengefasst. Hardwareersparnis: jeweils ein Multiplizierer weniger pro Doppelprozessor. 2.4.2.2 Invertierung von Dreiecksmatrizen Die Aufgabe ist, zu einen N × N -Matrix A die Inverse Matrix X zu finden mit A · X E. Wir = finden die Inverse A−1 durch Lösen von N Gleichungssystemen mit 0 0 A · Xi = Ei (Ei = 1 ← i-te 0 Komponente). Auf der Folie vom 7.5.07 finden wir dazu eine genaueres Programmbeispiel. Die Bewegungen der einzelnen Komponenten sind wie folgt: 1. aij von oben nach unten post(aij ) = (pos10(aij ) + t, pos20(aij )) 2. xij von links nach rechts post(xij ) = (pos10(aij ), pos20(xij ) + t) 3. tij gehen von rechts nach links post(tij ) = (pos10(tij ), pos20(tij ) − t) pos0( ) müssen jeweils entsprechend eingetragen werden. In Prozessor O: Einkommende aii t 1 1 werden invertiert: a und xi1 = ai1 berechnet. Der Wert a wird weitergereicht nach unten statt ii ii ii „aii“. 1 1 Prozessor ♦ nutzt dann in j-ter Zeile, j > 1 den Wert a , um xij = a · tij zu berechnen und ii ii 1 reicht a nach unten weiter. Die Laufzeit beträgt damit 3 N − 2 Wortschritte (Zeit, die ii gebraucht wird um t44 nach ♦ zu schieben). 21 2.5 Graphalgorithmen 2.5 Graphalgorithmen 2.5.1 Transitive Hülle Gegeben ist ein gerichteter Graph G = (V , E) mit |V | = N , V = {1, , N } und die Kantendarstellung erfolgt durch die Adjazenzmatrix A. Gesucht ist die Transitive Hülle G∗ = (V , E ∗) mit E ∗ = {(i, j)|es gibt einen gerichteten Weg in G von i nach j }. Dies werden wir mit dem aus der Vorlesung „Effizienten Algorithmen“ bekannten Warshall-Algorithmus lösen. Sei G(0) = G und G(k) = (V , E (k)) mit E (k) = {(i, j)| es gibt einen Pfad in G von i nach j mit Zwischenknoten höchstens aus {1, , k}}. Der Warshall-Algorithmus kann in dem Foliensatz vom 7.5.07 gefunden werden. Auch die genaue Implementation findet man dort. Da der Aufbau nicht wirklich trivial ist, einige Hinweise zu den einzelnen Berechnungen (Abbildung XX). Die Arbeit des Reflektors kann wie folgt beschrieben werden: (k−1) als Dadurch, dass Zeilen gestoppt werden (b) kommt aus der k-ten Spalte jeweils akk erstes zum Reflektor. Beobachtung: k-te Matrixzeile: • die akj , j k werden in der k-ten Prozessorzeile um genau n Schritte verzögert (bleiben dort stehen). Sie „sehen“ N Elemente der k-ten Matrixspalte vorbeiziehen. • Die Diagonalelemente akk regeln die Verzögerung (b) der Matrixzeile k und werden im rechten Reflektor um N Schritte verzögert (1. Stop + N − 1 Elemente aus k-ter Matrixspalte) Noch ein paar generelle Beobachtungen: • j-te Matrixspalte ◦ ◦ ◦ Bewertung wandert durch j-te Prozessorzeile Diagonalelement a jj erreicht diese Zeile stets als erste aus j-ter Matrixzeile Bei der Verzögerung von a jj passieren die Spaltenelemente in der Reihenfolge a j +1,j , a j +2, j , , a j+N −1,j . (Folie „Eingabe aus Sicht der k-ten ...“) 1. N (N + 1) Prozessoren, 2 · N Reflektoren 2. Distanz + Verzögerung = (4 · N − 2) + N = 5 N − 2 2.5.2 Weitere Probleme 2.5.2.1 Kürzeste Wege (Floyd) G = (V , E) und jede Kante hat Gewicht (i, j): wij und es gilt wii = 0. Dabei definieren wir • (0) wij = wij • wij = Länge eines kürzesten Weges von i nach j durch Knotenmenge höchstens {1, , k} • (k) (k−1) wij = min {wij , wik (k) Die Berechnungsvorschrift ist sehr ähnlich zum Warshall-Algorithmus. (k −1) (k −1) + wkj } Struktur ist wie vorher die transitive Hülle. 2.5.2.2 Minimale Spannbäume Kann mit ähnlicher Rekursionsstruktur gelöst werden (Plotkin-Verfahren). Weiterhin kann man auch Algebraische Pfadprobleme damit betrachten. 2.5.2.3 Rekurrente Gleichungssysteme Probleme auf Matrizen, die durch rekurrente Gleichungen beschrieben sind, lassen sich in ähnlicher Weise lösen, z.B. fk(aij ) = g(fk −1(aij ), fk−1(aik), fk −1(akj )), i j als transitive Hülle mit fk(aij ) = a(k) ij mit g(a, b, c) = a ∨ (b ∧ c) und fk(a ii) = aii ∀i. Kapitel 3 Datentransport und Sortieren auf Gittern Definition 3.1. Das Datentransportproblem besteht darin, die richtigen Daten in vertretbarer Zeit zum richtigen Platz zu bringen. Ein Datenpaket ist auf der Folie vom 10.5.07 dargestellt. 3.1 Ein Zusammenhang zwischen Routing und Sortieren Definition 3.2. (h-h Datentransport) 1. Ein h-h-Problem, h ≥ 1, ist ein Datentransportproblem bei dem jeder Prozessor anfangs höchstens h Pakete enthält und ziel von höchstens h Pakten ist. 2. Ein h-h-Problem, h ≥ 1, heißt voll, wenn jeder Prozessor anfangs genau h Pakete enthält. 3. Falls h = 1 heißt dsa Problem auch (partielles) Permutationsproblem (volles Problem = volles Permutationsproblem). Definition 3.3. 1. Eine Indexfunktion (Indizierung) g für eine Menge von Prozessoren M ist eine Durchnummerierung der Prozessoren von 0, , N − 1 mit N = |M |. g: M → {0, , N − 1} 2. ((volles) 1-1 Sortierungproblem) Seien in einem Netz von N Prozessoren anfangs N Elemente einer linear geordneten Menge so geladen, dass jeder Prozessor genau 1 Element enthält. 1-1 Sortierproblem bezüglich gegebener Indizierung g: Bringe das i-t kleinste Element in den mit i − 1 indizierten Prozessor, für alle i 1, , N. 1 Volles 1-1-Routing kann durch Sortieren gelöst werden. 1. Für jedes Paket mit Zielprozessor p kodiere Adresse P mit g(P ) für Indexfunktion g. 2. Sortiere Pakete gemäß kodierten Adressen mit 1-1-Sortieralgorithmus bezüglich g. 3.2 Odd-Even Trasposition Sort Siehe Folien vom 10.5.07. Der Algorithmus laufen so ab: • oets: ◦ for i 1 1 to N 2 do 1. odd-step; 2. even-step; ◦ end 23 24 Datentransport und Sortieren auf Gittern Bemerkung 3.4. Complex-Operationen sind im Voraus spezifiziert. Ort (Prozessor, Zelle) und Zeitpunkt aller Compex-Operationen und aller einfachen Datentransporte sind im Voraus festgelegt und hängen nicht von den Datenwerten ab. Algorithmus ist oblivious (vergessend - vergisst aktuelle Datenwerte). OETS ist ein solcher Algorithmus. Die Inhalte von Prozessor Pi und Pi+1 werden genau dann in Schritt t verglichen, wenn t + i ungerade ist. Lemma 3.5. (0-1 Prinzip) Wenn ein Algorithmus oblivious ist und alle beliebigen Eingabemengen, die nur aus Nullen und Einsen bestehen, sortiert, dann sortiert auch alle Eingaben von beliebigen Werten. Beweis. Angenommen, es gibt einen Vergleichsalgorithmus ALG, der oblivious ist und eine Eingabe x1, x2, , xN nicht korrekt sortiert, aber alle nur aus 0’en und 1’en bestehende Eingaben richtig sortiert. Sei π Permutation mit xπ(1) ≤ xπ(2) ≤ ≤ xπ(n) (d.h. π korrekte Lösungspermutation). Sei π Permutation, die ALG als Ausgabe erzeugt. Sei k kleinster Index mit xo(k) > xπ(k). • • Falls k = 1: xo(1) > xπ(1) falls k ≥ 2: xo(i) = xπ(i) für i, 1 ≤ i < k und xo(k) > xπ(k) ⇒ ∃r > k mit xo(r) = xπ(k). Sei x∗i = ( 0 xi ≤ xπ(k) 1 xi > xπ(k) ∗ . Insbesondere gilt: x∗π(k) = 0, xo(k) 1 1. Betrachte Verhlaten von ALG bei Eingabe, wobei jedes xi durch x∗i ersetzt ist. Da für alle i, j gilt xi ≥ x j dann auch x∗i ≥ x∗j führt ALG die gleichen Compex-Operationen auf x∗-Eingabe aus wie auf x-Eingabe. D.h. Ausgabe ∗ ∗ von ALG bei Eingabe der 0-1 Werte x∗1, , x∗o(k−1), xo(k) , , xo(r) . Also steht mal eine 1 vor einer 0 und die 0-1 Folge wurde nicht korrekt sortiert ⇒ Widerspruch zur Annahme. Lemma 3.6. Oets sortiert auf einem linearen Feld mit N Prozessoren in N Schritten. Beweis. Mit 0-1 Prinzip. Sei beliebig 0-1 Ladung der Prozessoren gegeben. Sei k Anzahl der Einsen. Pos 1 2 3 0-1 0 0 1 j2 .. j1 1 1 N 0 Tabelle 3.1. Sei ji die Position der i-ten Eins von rechts. • Spätestens nach dem ersten Schritt von Oets bewegt sich die am weitesten rechts stehende Eins immer in jedem Schritt um 1 Position nach rechts bis zur Position N . • 2-te Eins wird u.U. durch 1-te Eins behindert nach rechts zugehen. Aber nur in Schrit 1 und 2. Danach läuft sie unbehindert. Wegen ji ≥ k + 1 − i erreicht die i-te Eins spätestens nach i + N − i + 1 − ji Schritte zum Ziel und das ist natürlich ≤ N + 1 − (k + 1 − i) = N +i−k ≤ N 3.3 Row-Column Sort Darstellung und Algorithmus: siehe Folie vom 10.5.07. 25 3.4 Sortieren in O(n) auf n × n-Gitter Satz 3.7. Row-Column Sort sortiert ein 1-1 Problem auf einem n × n-Feld in 2 · n⌈log n⌉ + n Schritten. Beweis. (mit 0-1 Prinzip) Sei beliebige 0-1 Ladung gegeben. Mengen von Prozessorinhalten heißen schmutzig, wenn sie sowohl 0’en als auch 1’en enthalten. Sonst heißen sie sauber. Anfangs sind die zeilen schmutzig. 1. Sortiere Zeile alternierend • • dl Anzahl der Zeilen mit 1’en links dr Anzahl der zeien mit 1’en rechts d d aus der schmutzigen Region in der Mitte, d.h. dl + dr = d und dl , dr ∈ {⌊ 2 ⌋, ⌈ 2 ⌉}. Betrachte nun Spalte ( ∗ , j) mit maximal vielen Einsen. Die Anzahl der Einsen sei c1 + m. Sei m = ml + mr, wobei mr Anzahl der Einsen aus schmutziger Region mit 1’en rechts und ml aus Zeilen mit 1’en links. Aus der schmutzigen Region enthalten alle Spalten • • links von j mindestens ml Einsen rechts von j mindestens mr Einsen Also enthält jede Spalte mindestens c1 + min (ml , mr) Einsen. Nach Sortieren der Spalten bleiben höchstens d c1 + m − (c1 + min (ml , mr)) = max (ml , mr) ≤ max (dl , dr) ≤ ⌈ ⌉ 2 schmutzige Zeilen. Nach ⌈log n⌉ Schleifendurchläufen bleiben von anfangs n schmutzigen Zeichen höchstens √ noch eine schmutzige Zeile. Die wird in 2. sortiert. Row-Column Sort sortiert in O( N · log N ) = O(n log n) und benötigt dabei Ω(n log n) Schritte (Worst-Case). Im Mittel ist es weiterhin Ω(n log n). 3.4 Sortieren in O(n) auf n × n-Gitter Indizierung schlangenartig lexikographisch p1 · n + p2 falls p1 gerade lex − snake(p1, p2) = (p1 + 1) · n − p2 − 1 falls p1 ungerade 3.4.1 Ein einfaches Sortieren durch Mischen Der Mischschritt besteht daraus, aus 4 sortierten Teilfeldern erhalten. a 2 × a 2 ein sortiertes a × a-Feld zu Algorithmus merge( 2 , 2 ): a a 1. Sortiere Zeilen in a × a-Feld alternierend (kostet a Schritte) 2. Sortiere Spalten in a × a-feld nach unten (kostet a Schritte) 3. Führe 4 a Schritte des Oets (odd-even transposition code) entlang der gesamten Schlange durch (kostet 4a Schritte) 26 Datentransport und Sortieren auf Gittern Abbildung 17. Allgemein ist n n n n +M , , 2 2 2 2 n n = S , +6n 2 2 n n n +6· +6·n = S , 2 4 4 ⌈logX n⌉−1 n n 1 = S i, i + 6 · n · j 2 2 2 j =0 S(n, n) = S ? = S(1, 1) + 6 · n 0 ≤ 12 n ⌈logX n⌉−1 1 2j j =0 3.4.2 Sortieren in 3 n + o(n) auf einem n × n-Feld Satz 3.8. (Thompson/Kung, Schnorr/Shamir) Sortieren auf einem n × n-Gitter kann in 3 · n + o(n) Schritten ausgeführt werden. Die dafür genutzte Technik bezeichnet man als Supermischen (Folie „Shift um i Positionen“,‘ „Partitionierung eines n × n-Feldes). Behauptung zum Algorithmus: 3 1. Schritte 3.1 bis 3.3 sortieren Türme von Blöcken n × n 4 -Gitter. 1 P 4 D.h. in jeder Spalte c (Turmspalte) sind mindestens a = ni=1 hi Einsen und höch1 1 P 4 stens b = ni=1 (hi + 1) = a + n 4 Einsen. 1 2. Nach Schritt 3.2: nur eine zusammenhängende Region von höchstens n 4 Zeilen enthält schmutzige Zeilen. Wir unterschieden, wo ein Bereich D (dirty region) liegt in 2 Fälle: • • D liegt in Paar B2 j −1 ∪ B2 j ⇒ wird korrekt sortiert. D liegt in Paar B2 j ∪ B2 j +1 ⇒ Zuerst werden alle Paare B2j −1 ∪ B2j sortiert und dann B2j ∪ B2 j +1 ⇒ wird korrekt sortiert. Wie werden Paare von Blöcken sortiert? Bemerkung 3.9. Das Sortieren von Paaren von Blöcken ist äquivalent zum Sortieren von 2 a × a-Feldern. • • direkte Methode: wie einfachere Merge-Sort oder: 1. Sortiere a × a-Felder mit lex 2. Sortiere Spalten nach unten 3. 2 a Schritte von oets entlang der ganzen Schlange Beweis. (für Algorithmus aus Satz 3.8) • nach Schritt 1: ◦ ◦ Block Bij , 1 ≤ i, j ≤ n1/4 ist sortiert Block Bij erhält insgesamt an Einsen ai = n X j =1 zj∗ ≤ ≤ ai + n1/4 1/4 n X j =1 zjk ≤ 1/4 n X j=1 (z jk + 1) 27 3.5 Untere Schranken fürs Sortieren ◦ Jede Spalte (Turm) von Blöcken B1,k , , Bn1/4,k erhält mindestens x= i=1 Einsen. ◦ ai i=1 Einsen und höchstens 1/4 n X 1/4 n X (ai + n1/4) = x + n1/4 · n1/4 = x + n1/2 k j x Nach Sortieren der Türme von Blöcken sind in jedem Turm mindestens x = 3/4 l m n x + n1/2 (Block-)Zeilen nur mit Einsen gefüllt und höchstens Zeilen können 3/4 n Einsen enthalten. Also können nur höchstens die Gesamtzeilen y + 1 und y + 2 (von unten gezählt) schmutzig sein. Betrachte Turm von Blöcken mit maximalen Einsen. Sei b die Anzahl der Einsen in oberster Turmzeile, die noch Einsen enthält. 1 ≤ b ≤ n3/4. Falls b ≥ n1/2, dann enthalten alle anderen Türme nur Einsen in den Zeilen darunter. Nur Zeile d ist dann im Gesamtfeld schmutzig ⇒ Schritt 4 im Algorithmus reicht zum Sortieren. Falls 1 ≤ b < n1/2, dann kann es Türme geben, in denen Zeile d − 1 schmutzig ist. Diese Türme enthalten mindestens n3/4 − n1/2 + 1 Einsen, d.h. höchstens < n1/2 Nullen. Also enthält die gesamte Zeile d höchstens n1/4 · b < n1/4 · n1/2 = n3/4 Einsen und d − 1 hat höchstens n1/4 · n1/2 = n3/4 Nullen. Entlang der gesamten Schlage wandern etwa in obererer Zeile die Einsen nach rechts und in unterer Zeilen nach links. Nach n Schritten von oets entlang der gesamten Schlange. Mit weiteren 2 · n3/4 Schritten von oets ist alles sortiert. • Laufzeit des Algorithmus: ◦ ◦ ◦ 2x Sortieren von Blöcken 2x Sortieren von Doppelblöcken in O(n3/4) Shift (Schritt 2) ⇒ n ◦ Nach unten sortieren ⇒ n ◦ Schritt 4 ⇒ n + 2 · n3/4 3 · n + O(n3/4) 3.5 Untere Schranken fürs Sortieren • • n × n-Feld: Distanzschranke ist 2 · n − 2 Modell 1: Vor und nach jedem Schritt befindet sich genau ein Element (Paket) in jedem Prozessor. (oets erfüllt Modell 1). Shift (in Schritt 2 von Schnorr/Shamir-Algorithmus) geht mit oets in n Schritten. 3.5.1 Das Joker-Argument Satz 3.10. Sortieren auf dem n × n-Feld im Berechnungsmodell 1 benötigt mindestens 3 n − o(n) Schritte für lexikographische und schlangenartige lexikographische Indizierung. (auch für major-Indizierung) Beweis. Sei Indizierung schlangartig lexikographisch. column- 28 Datentransport und Sortieren auf Gittern Teile das Feld in 2 Zonen: • • Jokerzone (Dreieck links oben) Zone A: Rest Ladung in der Jokerzone: nur Nullen und n2’s (große Zahlen) √ Nach 2 n − ⌈2 · n ⌉ − 3 Schritten enthält Prozessor C irgendein j aus A. Dieses j ist unabhängig √ von der Ladung von der Jokerzone, weil es wegen des Abstands 2 n − ⌈2 · n ⌉ − 2 von JZ zu C nie mit einem Jokerelement in Berührung gekommen ist. Es gibt ein k ∈ N mit • (k − 1) · 2 n + 1 ≤ j ≤ k · 2 n Sei a0 = k · 2 n − j + 1 ≤ 2 n die Anzahl der Nullen in der Jokerzone, d.h. j bekommt Rang a0 + j = k · 2 n + 1 in der Gesamtladung. Dieses Element muss zum Prozessor mit Index k · 2 n + 1 − 1 = k · 2 n sortiert werden, d.h. es muss zum linken Rand. Damit haben wir insgesamt Schrittzahl √ 2 n − ⌈2 n ⌉ − 3 + n − 1 = 3 n − o(n) Satz 3.11. Für n × n-Gitter gilt folgendes: • • • Sortieren mit beliebiger Indexfunktion erfordert im Modell 1 mindestens 2.27 n Schritte, d.h. 2 n − 2 kann nicht erreicht werden. Es gibt Indizierungen für die mit Jokertechnik keine bessere Schranke als 2.5 · n gezeigen werden kann. Fast alle Indizierungen (n!) benötigen ≥ 3 n − o(n) Schritten beim Sortieren. 3.5.2 Bemerkungen zum Sortieren auf n × n-Gitter (siehe Folie vom 24.5.07 „Sortieren auf a × b-Feldern mit schlangenartiger Indizierung“). N Prozessoren liefern folgende Ergebnisse N = n2 Gitter untere+obere Schranke n×n ∼3n √ √ √ 1√ 1√ N = 2 n· 2 2 ·n 2n × 2 2 n ∼ 2 2n Bei einer anderen Aufteilung der N können wir also unter 3 n kommen Tabelle 3.2. Auf n × n Torus können wir es noch weiter verbessern: 1. schlangenartige Indizierung: 2.5 · n + O(n3/4) (Verallgemeinerung des Schnorr/Shamir; Shfit schneller) 2. Blockweise schlangenartige Indizierung: 2 n + O(n3/4) (Ma, Sen, Scherson 86) 3. beste untere Schranke für n × n-Tori im Modell 1: 1.5 · n für beliebige Indizierung (Kunde 1988) Bemerkung 3.12. Sortieren auf n × n-Tori prinzipiell schneller als auf n × n-Gitter ohne „wrap-arounds“. 3.6 Permutationsrouting Wir arbeiten im folgenden auf einem n × n-Feld. Volles 1-1-Routing können wir durch Sortieren in 3 n + o(n) lösen. 3.6 Permutationsrouting 29 Bemerkung 3.13. Im Modell 2 ist die Zwischenspeicherung von Paketen möglich und zwar bis zu f (n). (Prozessoren können leer sein!) 3.6.1 Greedy-Algorithmus Jeder Algorithmus, der jedes Paket auf einem kürzesten Weg zum Ziel bringt, kann als greedy angesehen werden. Algorithmus Greedy 1. In allen Zeilen: Transportiere Pakete in ihre Zielspalte. 2. In allen Spalten: Transportiere Pakete in ihre Zielzeilen. Satz 3.14. Falls Pufferung von n Paketen möglich ist, dann benötigt der „Greedy“-Algorithmus höchstens 2 n − 2 Schritte. Lemma 3.15. Auf einem linearen Feld mit n Prozessoren können folgende Probleme mit höchstens n − 1 Transportschritten gelöst werden: 1. anfangs ≤ 1 Pakete pro Prozessor 2. jeder Prozessor ist Ziel von ≤ 1 Paketen. Beweis. 1. o.B.d.A: nur Pakete von links nach rechts (Gegenrichtung stört nicht). Pakete marschieren im „Gänsemarsch“ in Richtung Ziel. Nach jedem Schritt sind mögliche vorausseiende Konkurrente um eine Kante mindestens um einen Schritt weiter. Am Ziel werden sie gepuffert und stören andere Pakete nicht. Maximale Distanz n − 1 wird in jedem Schritt uum 1 verringert. 2. o.B.d.A: nur Pakete von links nach rechts. Pakete wetteifern um dieselbe Kante. Priorität geben wir dem Paket, das noch am weitesten laufen muss. Im Schritt i: Pakete mit Ziel in I (aus A)heißen Prioritätspakete. In Zone A werden Prio-Pakete nie durch andere Nicht-Prio-Pakete behindert. Betrachte das am weitesten rechts stehende Prio-Paket (mit weitester Entfernung). (Siehe Folie vom 24.05.07). Da höchstens i Pakete in Bereich I wollen, ist max j ≤ i. Nach n − i + i − 1 = n − 1 Schritten haben alle Prio-Pakete den Bereich I erreicht. Beweisführung gilt für alle i = 1, , n − 1. D.h., alle Pakete haben nach höchstens n − 1 Schritten ihr Ziel erreicht. Bemerkung 3.16. 2 n − 2 gilt auch für Greedy-Algorithmen: nach Erreichen der Zielspalte versucht jedes Paket sofort die Zielzeile zu erreichen. Man kann zeigen: 2 Pufferung von ≥ 3 n − 2 Paketen kann nötig sein. 3.6.2 Randomisierte Algorithmen Verfahren von Valiant und Brebner 1. In jeder Spalte: Schicke Pakete in zufällige Zeilen: Mit hoher Wahrscheinlichkeit: • • ist ein Prozessor in Spalte c Ziel von höchstens O(log n) Paketen sind in einer Gesamtzeile höchstens n + O(log n) Pakete 2. Wende Greedy-Alg. an: n Schritte für 1. 2 n + O(log n) für 2. (Also insgesamt mit 3 n + O(log n) mit hoher Wahrscheinlichkeit). Eine Verbesserung findet man auf einer Folie vom 24.05.07 „Verbesserung: Rajasekaran/Tsantials“. Laufzeitbeweise für randomisierte Algorithmen sind schwierig und werden deswegen nicht angebracht. Der Beweis kann mit Chernoff-Schranken erfolgen. 30 Datentransport und Sortieren auf Gittern 3.6.3 Deterministischer Pakettransport mit kleinen Speicher Puffergröße f (n) Pakete/Prozessoren mit 4 ≤ f (n) ≤ bezüglich ihrer Adressen. P , Q seien Adressen. √ n . Lineare Ordnung auf Paketen gegeben P ≤ Q ⇔ lex(P ) ≤ lex(Q) Pakete mit Adresse (r, c) heißen auch Pakete mit Zeilenadresse r. Algorithmus 1. Teile das n × n in k 2 Bloecke der Groesse n k n × k. 2. In jedem Block sortiere Pakete bezueglich der lexikographischen Indizierung (row-major) Abbildung 20 3. In jeder Spalte: Transportiere für alle r, 0 ≤ r < n, Pakete mit Zeilenadresse r zum Prozessor in Zeile r. 4. In jeder Zeile: Transportiere Pakete in richtige Zielspalte. Kosten sind: • • n Schritt 2: O( k Schritt 3&4: 2 n f (n) f (n) n Satz 3.17. Sei 4 ≤ k ≤ 2 . 1 − 1-Routing kann in 2 n + O f (n) Schritten ausgeführt werden bei einem Puffer von Größe f (n). Bemerkung 3.18. 1. Sort-and-Route kann auch für a × b-Felder entworfen werden √ mit √a + b + o(a + b) Transportschritten (asymptotisch nahe an Distanzschranke, a ≥ b , b ≥ a ) n n 2. Auf n × n-Torus: 1-1-Routing in n + O f (n) . Auf Ring von Prozessoren 2 Schritt über Gänsemarsch. 3. Grundidee von Sort-and-Route anwendbar für h-h-Probleme, h ≥ 2. 4. konstanter Speicher? Satz 3.19. (Leighton, Makedon, Tollis, 1989) Permutationsrouting auf n × n-Gitter kann mit 2n − 2 Transportschirtten bei konstanter Puffergröße gelöst werden. Puffergröße war ursprünglich ≥ 1000. Kaufmann < 100. 3.6.4 Hot-Potato-Routing (siehe Folien). Wir unterscheiden zwischen greedy und pure greedy: • greedy: jedes Paket bewegt sich in Richtung Ziel, wann immer das möglich ist, d.h. wann immer die gewünschten Kanäle (Links) nicht schon an andere Pakete vergeben sind. pure greedy: ein Paket kann zurückgewiesen werden nur, wenn seine gewünschten Links an andere Pakete, die selbst Richtung Ziel wandern, vergeben sind. √ Satz 3.20. Für 1-1-Routing ist O(n · n · log n) eine obere Schranke für Pure Greedy Hot Potato Routing auf n × n-Gittern. √ Die Vermutung besteht, dass die obere Schranke bei O(n n ) liegt. • 3.7 Multi-Packet-Probleme Wir betrachten nun h-h-Routing für h ≥ 1. 31 3.7 Multi-Packet-Probleme 3.7.1 Sortieren Ausgangspunkt ist für uns nun 1-1-Sortieren auf einem linearen Feld mit 2 n Prozessoren. Abbildung 21. Zig-Zag-Sort 1. for i = 0 to n − 1 do odd (intern) • even (extern) • n+1 Satz 3.21. h-h-Sortieren auf einem Feld mit n Prozessoren kann mit (Transport-) 2 Schritten gelöst werden. (h ≥ 2) Die Indizierung dabei ist layer-last . (Siehe Folie „Indizierungen für Multi-Packet-Probleme) Algorithmus 1. Sortiere Blöcke 2. Shifte Daten Zeile (i, ∗ ): Layer 0: (i mod n1/4)n3/4 • Layer 1: n − (i mod n1/4) · n3/4 • 3. Sortiere Blöcke 4. Sortiere Spalten 5. Sortiere Paare von Blöcken 6. Sortiere entlang der ganzen Schlange Analyse der Transportschritte: • 1.,3.,5. dauert jeweils O(n3/4) • 2. Shift dauert n • 6. Zig-Zag-Sort dauernt n + 2 n3/4 • 4. Zig-Zag-Sort dauert n Also für eine 2-2 Ladung: 3 n + O(n3/4). Auf einem n × • • • 2. n 2 n 2 Feld: 2-2 Problem ergibt sich: 4.n 6. ∼ n 2 Also insgesamt in 2 n + o(n) möglich. 3.7.2 1-1-Sortieren in Modell 2 n × n-Feld: 1-1-Problem: n 4 ∈ N. Abbildung 22. 3.7.3 h-h-Sortieren mit Hilfe des All-to-all Mappings Abbildung 23 Beweis. (Laufzeit unixiale All-to-all Mapping) s. Folie „Uniaxiale All-to-all Mapping“ n n n Wir haben 4 Lagen, also Shifts der Form i, n − i, 2 − i, 2 + i mit 0 ≤ i < 2 . Auf einem Ring mit n Prozessoren können wir es folgendermaßen gestalten: Abbildung 24. Also ist Schritt 1 in n Schritten möglich. Bemerkung 3.22. Für h-h-Problem, h ≥ 4 können wir die Sortierung in h 2 · n + o(h · n). Bemerkung 3.23. Im Mittel kann mian die Sortierung noch weiter verbessern (siehe Folie „Sortierne im Mittel“. Kapitel 4 Hypercubes und verwandte Netzwerke 4.1 Der Hypercube r-dimensionaler Hypercube Hr , r ≥ 1 mit N = 2r Knoten. Jeder Knoten: String von r Bits und Kanten: u1u2 ur = (u1, u2, , ur), ui ∈ {0, 1} {(u1, , ui , , ur), (u1, , u¯i , , ur)} mit ū = (u + 1) mod 2 entlang der i-ten Dimension. Der Durchmesser eines Hypercubes ist r. 4.1.1 Einbettung von Feldern • Jeder N -Knoten-Hypercube enthält einen Hamilton’schen Kreis (Ring mit N Knoten Nachweis über Graycode: xi ∈ {0, 1}r , x1, x2, , x2r mit dH (xi , xi+1) = 1, dH (x2r , x1) = 1. Konstruktion mit Graycode w1, , w2r − 1 und ( 0wi i = 1, , 2r −1 (wi ∈ {0, 1}r −1 xi = 1w2r +1−i i = 2r −1 + 1, , 2r Bild eines Hypercubes: Abbildung 24 G = (V , E) ist Kreuzprodukt der Graphen G1 = (V1, E1), , Gk = (Vk , Ek) falls V = {(v1, , vk)|v ∈ Vi , 1 ≤ i ≤ k}, E = {{(u1, , uk), (v1, , vk)}|∃j mit (u j , v j ) ∈ E j und ui = vi ∀i, i j} G = G1 ⊗ G2 ⊗ ⊗ Gk n1 × n2 × × nk ist Kreuzprodukt von k linearen Feldern der Größe n1, n2, , nk. Für r-dim. Hypercube Hr: für alle k ≥ 1 und r = r1 + r2 + + rk gilt Hr = Hr1 ⊗ Hr2 ⊗ ⊗ Hrk. Hr ist 2 × 2 × × 2 Feld (r-mal). Hr = H1 ⊗ H1 ⊗ ⊗ H1 (r-mal). Lemma 4.1. Falls G = G1 ⊗ G2 ⊗ ⊗ Gk und G ′ = G1′ ⊗ G2 ⊗ ⊗ Gk′ und Gi sind Teilgraphen von Gi′ , ∀i, i = 1, , k, dann ist G Teilgraph von G ′. ′ Beweis. Für jedes i sei σi: Vi → Vi′. Diese Abbildung ist injektiv , die Kanten erhält, d.h. (vi , ui) ∈ Ei ⇒ (σi(vi), σi(ui)) ∈ Ei′. Sei σ(v) = (σ1(v1), , σk(vk)), v = (v1, , vk) ∈ V . Sei (u, v) ∈ E in G. Zu zeigen ist, dass (σ(u), σ(v)) ∈ E ′ gilt. Falls (u, v) ∈ E ⇔ ∃j: (u j , v j ) ∈ E j und ∀i, i j , ui = vi ⇒ für gleiches j (σ j (v j ), σ j (u j )) ∈ E j′ , d.h. Kante in G ′ und ∀i, i j gilt σi(ui) = σi(vi) ⇒ (σ(u), σ(v)) ∈ E ′. Also gilt: jedes 2r1 × 2r2 × × 2rk Feld (Torns) ist Teilgraph des Hr mit Dimension r = r1 + r2 + + rk weil lineares Feld mit 2ri Knoten ist Teilgraph von Hri. Jedes n1 × n2 × × nk-Feld ist Teilgraph des Hypercubes (HC) mit Dimension ⌈log n1⌉ + ⌈log n2⌉ + + ⌈log nk ⌉. 33 34 Hypercubes und verwandte Netzwerke Reicht nicht Dimension ⌈log(n1 · n2 · · nk)⌉? Dies geht nicht, denn z.B. ist ein 3 × 5 Teilgraphs des H4. Allgemein: n1 × n2 × × nk Feld ist Teilgraph von HC mit N Knoten gdw. N ≥ 2 ⌈log n1⌉+ +⌈log nk ⌉ Begriffe: 1. Einbettung. G = (VG , EG), H = (VH , EH ). G steht für Gastgraph (guest) und H für Wirtsgraph besteht aus 2 Abbildungen: f : VG → VH ∗ g: EG → EH ∗ mit EH Menge aller Pfade in H g(e), für e = (u, v) ∈ EG ist Pfad von f (u) nach f (v) in H. Pfad kann leer sein. 2. Teilgraph f injektiv und für alle (u, v) ∈ EG gilt g((u, v)) = (f (u), f (v)) ∈ EH . (kommt von VG ⊆ VH und EG ⊆ EH |VG × VG). ∗ 3. Dilation: maximale Streckung, die für eine Einbettung benötigt wird. g(e) = e1 ek ∈ EH . e = (u, v), e1 = (f (u), ), , ek = ( , f (v)), k ≥ 1. d = max |g(e)| e∈EG ist die Pfadlänge. Spezialfall: k = 0.f (u) = f (v). Beispiel: 3 × 5-Feld kann in HC mit 16 Knoten mit Dilation 2 eingebettet werden. Für 2-dimensionale Felder mit N Knoten: Einbettung f mit f injektiv in HC(mit 2 ⌈log N ⌉) ist möglich mit Dilation 2. 4. Expansion: |VH | |VG | 16 Beispiel: 3 × 5-Feld mit HC (als Wirt) ist möglich mit Expansion 15 und Dilation 2 bzw. 32 auch mit 15 und Dilation 1. (Tradeoff zwischen Dilation und Expansion). 5. Congestion (Stauwert oder potenzieller Stau) maximale Anzahl von Kanten des Ursprungsgraphen, die eine Kante des Wirtsgraphen bei Einbettung gemeinsam nutzen. Congestion ist gegeben durch max |{g(e)|e ∈ EG , ei ist Kante in g(e)}| ei ∈EH Maximale Mehrfachnutzung einer Kante. Bei Simulation (z.B. Packet-Routing) kann Stau an genutzter Kante ei ∈ EH entstehen. 6. Load (Last einer Einbettung) max |f −1(v)| v ∈VH f injektiv: Last 1 Was ist eine „beste“ Einbettung? Dilation, Expansion, Congestion und Load möglichst klein. 4.1.2 Einbettung von vollständigen binären Bäumen Ist vollständig binärer Baum mit N − 1 Knoten Teilgraph des HC mit N Knoten? Antwort: Nein, für N ≥ 8. Knoten r in Hr v = i1, , ir, ij ∈ {0, 1} hat gerade Parität ⇔ Anzahl der Nullen in i1, , ir ist gerade. Daraus folgt natürlich, dass ungerade Parität ⇔ Anzahl der Nullen ungerade. Der doppelt gewurzelte vollständige binäre Baum (DRCB: double rooted complete binary tree) Abbildung 25. Lemma 4.2. Ein DRCB-Baum mit N Knoten ist Teilgraph des Hypercubes mit N Knoten. 4.2 Butterfly, CCC (Cube-Connected Cycles), Benes-Netzwerk 35 Folgerungen daraus: • Ein vollständiger binärer Baum mit N − 1 Knoten kann in einen HC mit N Knoten mit Dilation 2 eingebettet werden. Ein der beiden DRCB-Wurzeln wird Wurzel des Binärbaums. • 2 vollständige Binärbäume mit 2 − 1 Knoten (Vereinigung) sind als Teilgraphen in einem HC mit N Knoten enthalten. N Jeder DRCB-Baum mit N Knoten enthält vollst. binäre Bäume mit 2 − 1 Knoten. N Beweis. Abbildung 26 N Nach Induktionsannahme enthalte jeder HC mit 2 Knoten, N ≥ 8, einen DRCB-Baum mit N N Knoten. Teile HC mit N Knoten in 2 Hypercubes mit jeweils 2 Knoten. Siehe Folie „Beweis2 idee“. Speziell zu beachten ist, dass die jeweils neu entstehenden DRCB-Teilbäume immer für Induktionsschritt geeignet sind. Ergebnis der Vereinigung ist bis auf Spiegelung ein linker Teilbaum (DRCB), der für Induktion gut ist. Mit einfacher Dimensionsvertauschung σ(x1x2x3 xr) → x2x1x3 xr erhält man aus gespiegelten A (siehe Folie „Beweisidee“) nun B (siehe Abbildung 27). Fakt ist, dass der vollst. bin. Baum mit N − 1 Knoten kein Teilgraph des Hypercubes mit N Knoten ist (Beweis in der Übung). Ein vollständiger Baum mit 2N − 1 Knoten kann durch in Hypercube mit N Knoten eingebettet werden. Abbildung 28 Bemerkung 4.3. Einbettung bel. binärer Bäume mit M Knoten • falls der Baum im Voraus bekann ist ◦ ◦ ◦ • Dilation O(1) M Load O N M Congestion O N dynamische Einbettung ◦ ◦ √ log N mit Load L deterministischer Algorithmus mit Dilation Ω L2 M randomisierter Algorithmus mit Dilation O(1) und Last von O N + 1 mit relativ hoher Wahrscheinlichkeit. 4.2 Butterfly, CCC (Cube-Connected Cycles), Benes-Netzwerk Nachteil des Hypercubes ist, dass der Knotengrad mit zunehmender Größe anwächst. Ausweg: Graphen, die dem Hypercube ähneln, aber konstanten Knotengrad besitzen. Ziel dabei ist, dass die Netzwerke beliebige andere Netzwerke ähnlich gut wie der der Hypercube simulieren. 4.2.0.1 Butterfly Der r-dimensionale Butterfly besitzt (r + 1) · 2r Knoten und r · 2r+1 Kanten. • • Knoten: < w, i > ◦ ◦ i ∈ N, 0 ≤ i ≤ r w = w1 wr Binärstring der Länge r Kanten: ( < w, i − 1 > , < w ′, i > ) ist Kante ⇔ 1. w = w ′ oder 2. w und w ′ unterscheiden sich nur im i-ten Bit 36 Hypercubes und verwandte Netzwerke HC ⇒ zusammengefalteter Butterfly • alle Knoten < w, i > → w im HC Erstes Ergebnis: Jeder Schritt eines Algorithmus auf einem HC mit N Knoten kann auf einem Butterfly mit N (log N + 1) Knoten in 2 · log N Schritten simuliert werden. 4.2.0.2 Wrapped-Butterfly In jeder Zeile werden die Level 0 und r miteinander identifiziert. < w, 0 > = < w, r > Resultat: r 2r Knoten, jeder Knoten hat Grad 4. 4.2.1 Benes-Netzwerke Ein r-dimensionales Benes-Netzwerk besteht aus 2r + 1 Leveln, wobei jeder Level genau 2r Knoten enthält. Die ersten r + 1 Level und die letzten r + 1 Level formen jeweils einen r-dimensionalen Butterfly. • • 1, , r + 1: Vorwärts r + 1, , 2r + 1: Rückwärts Benes-Netzwerke sind „rearrangeable“. Definition 4.4. Ein Netzwerk mit N Eingaben und N Ausgaben heißt rearrangeable. ⇔ Für jede Permutation Π von {1, , N } → {1, , N } gibt es eine Menge von Kantendisjunkten Wegen zwischen dem i-ten Input und dem Π(i)-ten Output für alle i ∈ {1, , N }. Für ein r-dim. Benes-Netzwerk können wir sogar 2 Inputs für jeden Knoten auf Level 0 und 2 Outputs für jeden Knoten auf Level 2r verwenden. Satz 4.5. Sei π eine beliebige bijektive Abbildung der 2r+1 Inputs auf die 2r+1 Outputs eines rdim. Benes-Netzwerkes. Dann gibt es eine Menge von kantendisjunkten wegen Pi, derart, dass jeweils jeder Input i mit Output π(i) verbunden ist. Beweis. Induktion über r. Abbildung 29 4.2.2 CCC - Cube-connected-cycles siehe Folie „CCC (...), Ähnlichkeit ...“. Generelles Prinzip: Ersetze jeden Knoten des Hypercubes durch einen Kreis (Ring) vom Grad r. Jeder Wrapped Butterfly mit N Knoten kann jeden Schritt eines CCC mit N Knoten in O(1) Schritten simulieren und umgekehrt. 4.2.3 Simulation beliebiger Netzwerke Ziel hier ist die Simlation eines beliebigen Netzes auf einem Wrapped Butterfly. Satz 4.6. Auf einem Wrapped-Butterfly mit N Knoten kann das 1-1-Routing von Paketen offline in ≤ 3 log N Schritten gelöst werden. Dabei befinden sich zu jedem Zeitpunkt höchstens 3 Pakte in jedem Knoten. 4.2.3.1 Off-line Permutationsrouting auf einem a × b-Gitter Gegeben ist dabei ein a × b-Gitter in Zelle (r, c) befindet sich zu Beginn das Paket Pr,c. Das Ziel von Pr,c ist dabei π(r, c) = (π1(r, c), π2(r, c)) bzw. π(p) = (π1(p), π2(p)). Der Algorithmus läuft dann so ab: 1. In jeder Zeile führe eine Permutation derart aus, dass danach in allen Spalten c die entsprechenden Pakte P1,c , , Pa,c bezüglich π1(Pi,c) ein 1-1 Problem beschreiben (d.h. bezüglich der Zeilenadressen). 37 4.3 Sortieren 2. In jeder Spalte transportiere Pakete P zu ihren richtigen Zeilenadressen π1(P ). 3. In jeder Zeile transportiere Pakete P zu ihren richtigen Spaltenadressen π2(P ). Dabei können Schritte 2 und 3 natürlich mit dem bekannten Greedy-Algorithmus behandelt werden. Als Beispiel kann Abbildung 30 betrachtet werden. Wie Schritt 1 im Algorithmus bestimmt wird, kann auf der Folie „Anwendung von bipartitem Matching“ nachgelesen werden. Beweis. Satz 4.6. 1. Schritt: Off-line 1-1-Routing auf Gitter für den Wrapped-Butterfly nutzen. Die Idee dabei ist, die Pakete so zu betrachten, als ob sie in einem 2r × r-Gitter von Prozessoren mit N = r · 2r liegen würden. Prozessor (i, j) im Gitter 0 ≤ i < 2r, 1 ≤ j ≤ r entspricht dem Knoten < bin(i), j > (auf r Stellen auffüllen (vorne mit 0)) im Wrapped-Butterfly. 1-1-Routing entspricht nun einer bijektiven Abbildung der Form: π: {0, , 2r − 1} → {0, , 2r − 1} × {1, , r} Daraus folgt nun, dass es ein 1-1-Routing auf dem Gitter entspricht, dieses Lösen wir mit dem offline-Routing. Die Permutation in Phase 1 und 3 finden auf den Zeilen statt, die im Wrapped-Butterfly r Ringe von r Prozessoren sind ⇒ 2 Schritte im schlechtesten Fall und höchstens 3 Pakete pro Prozessor (eins da, eins von links, eins von rechts). Für Phase 2 benutzen wir das offline Routing. Siehe Folie „Bew von Theorem 4.3“ Them 4.2 stellt sicher, dass dabei immer höchstens ein Paket in jedem Knoten ist und jede Kante wird immer nur von einem Paket genutzt. Alle Pakete einer Spalte sind stets im selben Level. Dadurch behindern sich die Spalten nicht und wir können die Bearbeitung der Spalten gleichzeitig durchführen. Daraus können wir schlussfolgern, dass Phase 2 genau 2r-Schritte benötigt und damit insgesamt 3r < 3 logN ist, denn log N = log (r · 2r) = r + log 1. Frage: Wie erhalten wir dass 1-1-Routing auf dem 2r × r-Gitter? ⇒ Folie „Simulation beliebiger Netzwerke (Graphen)“ Satz 4.7. Jeder parallele Schritt in G kann mit 3 d log N Schritten im Wrapped-Butterfly simuliert werden. Beweis. Kommunikationsschritt auf G ist ein d − d-Routing (d = maximaler Grad in G) ⇒ übersetze in d 1-1-Routings. Diese werden auf dem Wrapped-Butterfly simuliert ⇒ also < 3 log N Schritte pro 1-1-Routing und damit < 3 d · log N Schritt pro Kommunikationsschritt. Frage ist nun, wie schaffen wir es die d-d-Routings zu d 1-1-Routings umzuwandeln ⇒ bipartites Matching, siehe Folie mit Theorem 4.4. 4.3 Sortieren Bemerkung 4.8. Sortieren von N Elementen auf dem log N -dimensionalen • • Bufferfly in O(log 2 N ) Schritten Hypercube in O(log2 N ) Schritten Ein bekannter Algorithmus dafür ist Butcher’s Odd-Even-Mergesort. 4.3.1 Butcher’s Odd-Even-Mergesort Der Merge-Schritt besteht aus Eingabe A = a0, , aM −1 und B = b0, bM −1 mit M = 2k und A und B vorsortiert. even(A) = a0, a2, , aM −2 und odd(A) = a1, a3, , aM −1. Weitere Einzelheiten stehen auf der Folie. 38 Hypercubes und verwandte Netzwerke 4.4 Packet-Routing 4.4.1 Der Greedy-Algorithmus Wir betrachten das Problem auf einem (log N )-dimensionalen Butterfly betrachten. Jeder Knoten auf Level 0 < u, 0 > enthält Paket mit Ziel < π(u), log N > auf Level log N , wobei (end-to-end-Problem). Greedy-Algorithmus π: [0, N − 1] → [0, N − 1] • Paket in Prozessor < u1, , ulog N , 0 > , Adresse Prozessor < a1 alog N , log N > • Korrektur der Bits nacheinander, zuerst das erste Bit, dann das zweite usw. Beispielfolie: „Spiegelung“. Satz 4.9. Jedes (end-to-end) Routing-Problem auf einem log N-dimensionalen Butterfly wird √ √ durch den Greedy-Algorithmus in O( N ) Schritten gelöst, wobei die Puffergröße O( N ) sein muss. Bemerkung 4.10. √ 1. Größe des Puffers beim Greedy-Algorithmus muss Θ( N ) Pakete umfassen. 2. Falls Puffergröße nur O(1), dann benötigt der Greedy-Algorithmus Ω(N ) Schritte für einige Permutationen. √ 3. Für kleines N ( ≤ 100) sind N und log N nicht allzu verschieden, für große N ist log N sehr viel schneller. 4. Greedy-Algorithmus: • • • schlecht im worst-case recht gute für die meisten Permutationen: log N + o(log N ) Für einige nützliche Klassen sogar optimal: log N Schritte 4.4.1.1 oblivious Routing Definition 4.11. Ein Routing-Algorithmus heißt von dessen Ursprungs- und Zieladresse abhängt. vergesslich, wenn der Pfad eines Paketes nur In der Praxis ist dies sehr relevant, da es einfach ist. Es besitzt jedoch schlechtes Verhalten im Worst-Case. Satz 4.12. Sei G = (V , E) mit |V | = n und Grad ≤ d gegeben. Für jeden oblivious Routingalgo√ rithmus gibt es ein 1-1-Routing-Problem, für dessen Lösung der Algorithmus mindestens Schritte benötigt. N d Bemerkung 4.13. Greedy-Algorithmus ist natürlich oblivious. 4.4.2 Spezielle Routingprobleme Packing Problem • • • • Netzwerk ist gespiegelter Butterfly M ≤ N Pakete in Level log N eines Butterfly’s mit N Eingaben, höchstens 1 Paket pro Prozessor Transportiere die Pakete in die ersten M Prozessoren auf Level 0 derart, dass die relative Ordnung der Pakete nicht verändert wird. Route das i-te Paket auf Level log N (von oben gezählt) in den Prozessor < bin(i − 1) siehe Folie: „Beispiel für Packing-Probleme“ Die Indexberechnung erfolgt dabei mit paralleler Präfixberechnung (möglich in O(log N )). Dabei wird der vollständige Binärbaum in einen Butterfly eingebettet. Dabei ist zu bemerken, dass die durch den Greedy-Alg. bsetimmten Pfade knotendisjunkt sind. Ein Beweisskizze dafür befindet sich auf der Folie „Packing“.