Hybrides Scheduling - Professur für Technische Informatik

Werbung
Hybrides Scheduling
Ronald Moore, Melanie Klang, Bernd Klauer, und Klaus Waldschmidt,
Technische Informatik, J. W. Goethe-University, Frankfurt, Germany
Veröffentlicht in: ARCS ’99: Architektur von Rechensystemen 1999; Vorträge der Workshops im Rahmen der 15. GI/ITG Fachtugung, S. 211–218, Okt. 1999, Universität Jena, Institut für Informatik.
Kurzfassung
In dieser Arbeit wird ein hybrider Ansatz zur automatischen Parallelisierung von Computerprogrammen vorgestellt. Das Merkmal hybrid“ bezieht sich dabei auf das Scheduling, das teilweise zur Compilezeit und
”
teilweise zur Laufzeit durchgef ührt wird. Die Verlagerung des Schedulings in das eine oder andere Zeitfenster wird über die Berechenbarkeit der Ausführungszeitpunkte getroffen. Das Scheduling z.B. von Iterationen
mit a priori unbekannter Wiederholungszahl wird zur Laufzeit berechnet. Die Ausführungsreihenfolge von
Operationen in zyklusfreien Programmbereichen wird demgegenüber bereits zur Compilezeit berechnet. Aus
diesem Kriterium ergibt sich die Granularität der Module in den einzelnen Zeitfenstern: feingranulare Strukturen werden zur Compilezeit und grobgranulare zur Laufzeit in den Ablaufzeitplan eingetragen. Aufgrund
der hohen Anzahl feingranularer Strukturen kann ein großer Teil des Aufwandes für das Scheduling von der
Laufzeit in die Compilezeit verlagert werden.
1
Einleitung
1.1
Motivation und Überblick
Die parallele Programmierung sowie allgemein die
Parallelisierung von Algorithmen werden als schwierige Probleme angesehen (z.B.[13]). Unter dieser
Tatsache leidet die Akzeptanz von Parallelrechnern bei Programmierern, Anwendern und dadurch
auch bei der marktorientierten Rechnerindustrie. Das
Parallelisierungsproblem besteht in der (korrekten)
Verteilung von Daten und Programmteilen auf die
verfügbaren Ressourcen.
Dieser Beitrag stellt einen hybriden Ansatz zur automatischen Parallelisierung von Computerprogrammen vor, der das statische Generieren von Threads
mit dem dynamischen Scheduling verbindet. Feingranulare Scheduling-Entscheidungen bei der Generierung der Threads werden zur Compilezeit und
grobgranulare (Scheduling der Threads) zur Laufzeit
getroffen.
Der Ansatz besteht aus zwei Komponenten: Erstens aus der zur statischen Analyse (Threadgenerierung) notwendigen Compilertechnologie und zweitens aus einer Architektur, die das Scheduling und
die Verteilung von Threads unterstützt. Das Architekturkonzept ist hierbei selbst verteilt: Jedem Prozessor ist ein Broker zugeteilt, der gemeinsam mit
Diese Arbeit wurde von der Deutschen Forschungsgemeinschaft unter der Referenznummer WA 357/15-1 unterstützt.
anderen Brokern die Verteilung der Threads erledigt.
Siehe Bild 1. Hier werden 3 Strategien unterschieden: Die hier als attraktive Strategie bezeichnete Vorgehensweise versucht Threads von anderen Ressourcen abzuwerben“. Die dissipative Strategie versucht
”
Threads auf andere Ressourcen zu verdrängen. Eine kooperative Strategie versucht gemeinsam mit anderen Brokern eine günstige Verteilung zu ermitteln. Die hier verwendete Strategie stellt eine Mischform dar, bei der die Broker grundsätzlich kooperativ
arbeiten, sich aber mit zunehmender Belastung der
von ihnen verwalteten Ressource dissipativ verhalten. Genauso agieren die Broker bei Entlastung zunehmend mit einer attraktiven Strategie.
Zusammen verwalten diese Broker einen verteilten gemeinsamen Speicher DSM (Distributed Shared
Memory), und einen verteilten gemeinsamen Scheduler. Jede Kombination eines Prozessors, eines Brokers und eines lokalen Speichers wird im folgenden Attraction Memory Site (kurz: Site) benannt, wie
in einer Cache Only Memory Architecture (COMA),
vergleiche [5].
Die in diesem Beitrag beschriebene Rechnerarchitektur SDAARC (Self Distributing Associative ARChitecture) stellt Strukturen bereit, die die Laufzeitkomponente des Schedulers unterstützen. Zusätzlich wurde auf die Skalierbarkeit der Architektur geachtet.
Das wesentliche Ziel dieser Arbeit ist jedoch die
Vereinfachung der Programmierung. Das hier dargestellte Konzept übernimmt die komplette Aufgabe
der Verteilung von Daten und Berechnung und hat
als solches das Potential das Programmieren paralleler Systeme nahezu so einfach wie das sequentieller
Systeme zu gestalten. Ein Toolkit, das diese Zerlegung und Verteilung erledigt befindet sich in der Entwicklung.
1.2
Hintergrund
Der Ansatz dieses Beitrags bringt zwei Konzepte bisher unabhängiger Bereiche zusammen: Multithrea”
ded Architectures“ (Mehrfädige Architekturen) auf
der einen und Cache Only Memory Architectures“
”
(COMAs) auf der anderen Seite. Die Konzepte der
mehrfädigen Architekturen finden Verwendung, indem sie die grundlegenden Scheduling-Begriffe (siehe [2] oder [12]) definieren. COMAs stellen die Konzepte bereit, um einen DSM zu realisieren, so daß
Daten frei von einem lokalen Speicher zu einem anderen wandern können [5, 14, 15].
Bisher waren die Fragen bezüglich Verteilung von
Daten und Verteilung von Berechnungen strikt voneinander getrennt. Die mehrfädigen Architekturen
sagten wenig über die Datenverteilung aus und
COMAs ließen das Problem der Programmaufteilung sowie des Schedulings beim Programmierer.
Diese Aufteilung vereinfachte die Entwicklung beider Seiten. Nun ist jedoch ein Punkt erreicht, indem
durch das Aufheben der Grenze und der Optimierung
beider Komponenten (Scheduling und DSM) signifikante Fortschritte erzielt werden können.
Diese Kombination von COMA und Multithreading
nennen wir SDAARC, nach Self Distributing Associative ARChitecture [9, 10].
Adaptive Verteilung von Berechnung wird auch in
verschiedenen Forschungprojekten untersucht, die
migrierende Threads implementieren, z.B. [4] oder
[16]. Hier erfolgt die Datenverteilung — wenn überhaupt — über völlig andere Mechanismen als die
Verteilung von Berechnungen. Weiter ist die Definition eines Threads wesentlich komplizierter. Dadurch
entstehen Probleme, z.B. die Verteilung des Stacks,
die in SDAARC nicht vorkommen.
Der Rest dieses Beitrags ist folgendermaßen gegliedert: Abschnitt 2 gibt einen Überblick über
die umfassende Strategie und die Hard- und Software (Compiler) Voraussetzungen von SDAARC.
Abschnitt 3 stellt die Compilertechnologie und
Abschnitt 4 das Protokoll der Laufzeitverteilung
ausführlicher vor. Abschnitt 5 gibt eine Zusammenfassung.
2
Überblick
2.1
Strategie, Vorgehensweise
In SDAARC werden sowohl Daten als auch Berechnungen als Bevölkerung wandernder Objekte betrachtet. Die zentrale Idee ist zum einen Objekte einer angemessenen Granularität zu bestimmen, zum
anderen diese zur Laufzeit, entsprechend den aktuellen Gegebenheiten, zu verteilen. Dabei muß die Verteilung die Balance finden zwischen Lokalität (um
Kommunikationskosten zu reduzieren) und Parallelität (um die Gesamtlaufzeit zu reduzieren).
Aus dieser Vorgehensweise entstehen zwei Bereiche zur Lösung des Problems der Verteilung: Erstens müssen Objekte angemessener Größe zur Compilezeit aus dem Quellcode eines sequentiellen Programms extrahiert werden. Zweitens müssen diese
Objekte zur Laufzeit auf die zur Verfügung stehenden Attraction Memory Sites abgebildet werden. Als
solches besteht SDAARC aus zwei Hauptgebieten:
der Compilertechnologie zum Extrahieren der Objekte und der Laufzeittechnologie für deren Verteilung.
2.2
Hardware Anforderungen
SDAARC stellt nur geringe Anforderungen an die
Hardware, um das Konzept zu implementieren. Wie
schon angesprochen, ist die Hardware in eine Menge von Attraction Memory Sites zu organisieren, wobei jede Site aus einem oder mehreren Prozessoren,
einem Broker, einem Speicher und einem Netzwerk
besteht. Zusätzlich könnten mehrere Sites gruppiert,
und durch einen zusätzlichen Gruppen-Broker repräsentiert werden, um hierarchische Systeme zu bilden.
Die Implementierung der Broker in Hardware, Software oder Mischformen ist freigestellt. Auch für das
Netzwerk sind unterschiedliche Topologien möglich,
wie beispielsweise Baumstrukturen oder Kreuzschienenverteiler [10].
Die Broker und das Netzwerk sind zusammen maßgeblich für die Umsetzung der SDAARC Strategie
verantwortlich. Da das Programm mit den zugehörigen Daten als Bevölkerung wandernder Objekte verstanden wird, werden fast alle Nachrichten, die über
das Netzwerk ausgetauscht werden, an Objekte und
nicht an Speicherzellen adressiert. Jede Nachricht
muß daher an alle Broker versendet werden, deren
Sites den Empfänger momentan enthalten könnten.
Attraction Memory Site A
Processor A
Attraction Memory Site B
Memory A
Environment
Processor B
Broker A
NETWORK
Broker B
Memory B
Bild 1. Abstraktes Schemata für ein Architekturkonzept mit verteiltem gemeinsamen Speicher (DSM:
Distributed Shared Memory) und verteiltem gemeinsamen Scheduler
Compiler Front Ends
C Front End
Compiler Back End
Thread Partition
Neural Network
Specifications
Dataflow
Graphs
Emulator
Code Generator
Hardware
Other Languages
Bild 2. Compiler Technologie zur Repräsentation von Programmen als Threads
2.3
Compiler Anforderungen
SDAARC setzt voraus, daß jedes Programm durch
eine Menge von Microthreads repräsentiert wird. An
dieser Stelle soll zuerst die Bedeutung des Begriffs
Thread für diesen Beitrag genauer definiert — da
dieser unglücklicherweise mit verschiedenen, oft widersprüchlichen Bedeutungen in der Literatur verwendet wird. Die Terminologie in diesem Beitrag
entspricht der von [12]: Ein Microthread sei eine atomare Untermenge eines Datenflußgraphen, die niemals auf Daten oder Ereignisse wartet. Muß ein Prozeß z.B. auf ein Eingabedatum warten, wird dieser
in mindestens zwei Microthreads geteilt. Der erste
resultierende Microthread führt die Berechnung bis
zu dem Punkt durch, an dem die Eingabe notwendig
wird, der andere startet nach Ankunft des Datums.
Microthreads werden vom Compiler, und nicht vom
Programmierer, festgelegt. Die Compilertechnologie
um sequentielle Programme in Threads zu übersetzen ist in Bild 2 dargestellt. Diese kann in Frontund Back-End aufgeteilt werden. Das Front-End ist
für die Übersetzung eines sequentiellen Programms
in einen Datenflußgraphen verantwortlich. Die Wahl
der Quellensprache ist dem Programmierer überlassen, und kann entsprechend den benötigten Eigenschaften zur Problemlösung gewählt werden. FrontEnds für eine Untermenge von ANSI C und eine
Sprache zur deklarativen Spezifikation Neuronaler
Netzwerke sind in [11] und [8] beschrieben. Datenflußgraphen wurden aus zwei Gründen als Zwischenformat gewählt: erstens, um Unabhängigkeit
zur Quellensprache zu erreichen, und zweitens, um
den im sequentiellen Programm implizit enthaltenen
Parallelismus sichtbar und greifbar zu machen.
Das Back-End besteht aus zwei Schritten: Zunächst
wird der Datenflußgraph in Microthreads aufgeteilt
und danach für jeden dieser Threads separat Code
generiert. Während letzteres weitestgehend mit konventionellen Techniken erfolgt, wird die Graphpartitionierung in Abschnitt 3 näher vorgestellt.
3
Die Compiler Technologie
3.1
Algorithmus zur Graphpartitionierung
Die Autoren haben einen ersten Entwurf zur Partitionierung von Graphen realisiert, um das SDAARC
Konzept empirisch bewerten zu können. Dieses
Werkzeug akzeptiert Datenflußgraphen der in [11]
und [8] beschriebenen Front-Ends und weist jedem
Knoten einen Index zu, der die Position des Knotens
in einem hierarchisch organisierten Baum von Untergraphen angibt.
Der Algorithmus verfährt in zwei Schritten: Im ersten Schritt werden verschachtelte Kontrollstrukturen
identifiziert und diesen Macrothreads“ zugewiesen.
”
Das Resultat dieses Schritts ist ein hierarchischer
Graphpartitionierungsbaum, dessen innere Knoten
Macrothreads repräsentieren und dessen Blätter nun
gerichtete, azyklische Datenflußgraphen enthalten.
Im zweiten Schritt wird jeder gerichtete, azyklische
Untergraph weiter in Microthreads zerteilt. Dies ist
momentan durch einen greedy, bottom-up Packalgorithmus realisiert, der heuristisch versucht eine Kostenfunktion zu minimieren. Zu Beginn des zweiten
Schritts wird jedem Knoten ein individueller Microthread zugewiesen (jeder Microthread besitzt also zu Beginn genau einen Knoten). Sodann werden Paare von Microthreads ausgewählt und zusammengefügt, dann und nur dann, wenn der Zusammenschluß die Kostenfunktion nicht verschlechtert
und dadurch kein Zykel innerhalb des Macrothreads
entsteht.
Für die Kostenfunktion wird jedem Knoten ein statischer Kostenfaktor zugewiesen, der dessen Berechnungszeit repräsentiert. Analog erhält jeder Kante zwischen zwei Microthreads einen statischen
Kostenfaktor entsprechend der Durchschnittszeit
bezüglich Kommunikation und Kontextwechsel. Die
Kosten des gesamten Untergraphen entsprechen somit den Kosten entlang des kritischen Pfades.
Formaler ausgedrückt: Sei
ein azyklische (Teil-) Datenflußgraph vor der Partitionierung,
die Menge der Knoten und
wobei
die Menge der Kanten ist.
Sei weiter
eine Partitionierung von .
Hier stellt ein Microthread
eine Menge feingranulare Operationen dar:
. In
ähnliche Weise stellt eine Kante
in der Partitionierung eine Menge feingranularer Kanten dar.
Alle feingranularen Kanten in einer grobgranularen
Kante gehen vom selben Microthread zum selben
Microthread:
!"#"%& $'."(-/")*$0+1-%,( 1-2 33-5-746481- -:9;3-=<> ? -:4@-
"#"%&A$'"")*$ +B4 " C-"$ D- <E - 9F&()4G C- '+B4H DI J - ; ILK MK NPOQ I JWP
OXILYJZ#[#Z#K \]RZ_S^3TVU` W"A"2- $ -ba W - 4G - `
OXILc Z#Md ^` "%"e- $ W - a W - 4f - `
I & A & I K MK N
I YJZ#[#Z#K \]Z
ILc Z#Md
Zuerst definieren wir die Kosten eines Microthreads:
wobei
die Kosten für einen feingranularen
Knoten sind;
die Zeit darstellt, die für einen
Thread-Wechsel notwendig ist;
die Zeit darstellt, die notwendig ist, um einen Nachricht zu empfangen; und
die Zeit darstellt, die notwendig
ist, um eine Nachricht zum Netzwerk zu schicken.
Anders gesagt sind die Kosten eines Microthreads
gleich der Summe der Kosten, um alle Operanden
zu empfangen, plus die Summe der Kosten für alle
Rechenoperationen im Microthread, plus die Summe
der Kosten, um alle Ergebnisse in das Netzwerk zu
übertragen.
1[#- YJK N <!- 1 - <1#[ YJK N
Nun können wir die Kosten des kritischen Pfades,
und damit auch die Kosten des Graphen definieren.
die Menge alle Microthreads am kriSei
tischen Pfad, und
die Menge alle grobgranularen Kanten am kritischen Pfad. Dann beträgt
die minimale Rechenzeit für den Graphen
I A1g I % [#YJK N IL[#hiji@^` [#- YJK N `O Q I A - T U lS k 2m U npo q
IL[#hiji
wobei
die Zeit ist, die eine Nachricht im
Netzwerk verbringt.
Die Modellierung von Kommunikationskosten ist der
LogP Methode ähnlich, vergleiche [3].
Der Algorithmus kann mit verschiedenen Werten für
und
auf gegebene Hardware angepaßt werden. Die Partitionierung
bleibt jedoch für beliebige Werte korrekt. Empirische Ergebnisse mit verschiedenen Werten werden
im nächsten Abschnitt (Abschnitt 3.2) dargestellt.
Die Berechnung des kritischen Pfades wird hier drei
Ansprüchen gerecht: Erstens werden über diesen die
Knoten ausgewählt, deren Zusammenschluß diskutiert wird. Zweitens kann die Kostenabschätzung einfach über eine neue Berechnung aktualisiert werden.
Zuletzt erkennt die Berechnung des kritischen Pfades, ob ein Zusammenschluß zweier Microthreads
einen Zyklus erzeugt.
Das Werkzeug zur Partitionierung ist ausführlicher in
[7] beschrieben.
I A3r I K MK N I YJZ#[#Z#K \Z ILc Z#Md I [#hiji
3.2
Erste Resultate
Gezeigt wird das Resultat des zweiten Schritts für
zwei Beispiele: zum einen für einen regelmäßigen
Graphen (Matritzenmultiplikation) zum anderen für
einen unregelmäßigen Graphen (zufällig generierter
Graph mit 160 Knoten). Desweiteren werden zu jedem Beispiel zwei mögliche Partitionierungen dargestellt: eine unter der Annahme von extrem optimistischen (niedrigen) und eine mit realistischeren
(höheren) Kommunikationskosten.
Der regelmäßige Graph repräsentiert die Berechnung
einer 3x3 Matritzenmultiplikation. Dieses Beispiel
wurde nicht als absolut typisches Beispiel gewählt,
sondern vielmehr weil die Struktur bekannt und der
18
69
65
67
12
51
15
47
10
49
8
75
9
71
7
73
29
31
1
33
59
5
61
6
63
19
13
57
16
53
11
55
21
41
2
20
43
14
3
45
17
35
4
37
39
23
25
66
48
72
30
60
54
42
36
24
68
50
74
32
62
56
44
38
26
70
52
76
34
64
58
46
40
28
83
80
84
77
82
81
79
78
22
27
Bild 3. Partitionierung einer 3x3 Matritzenmultiplikation unter der Annahme optimistischer Kommunikationskosten ergibt 36 Microthreads
7
6
5
53
19
16
13
47
12
2
15
35
3
18
4
1
11
29
41
14
17
8
23
21
71
9
20
10
65
59
55
54
49
48
37
36
31
30
43
42
25
24
73
72
67
66
60
61
57
56
51
50
39
38
32
33
45
44
27
26
75
74
69
68
63
62
58
52
40
34
46
28
76
70
64
81
80
78
77
79
22
84
83
82
Bild 4. Partitionierung einer 3x3 Matritzenmultiplikation unter der Annahme realistischerer Kommunikationskosten ergibt 9 Microthreads
5
22
17
72
34
30
63
32
73
99
86
49
82
150
130
119
1
158
48
42
101
53
75
140
124
104
112
131
125
31
28
71
46
109
129
143
16
87
19
21
111
44
68
133
78
77
51
80
94
70
91
105
4
113
93
36
126
148
6
26
38
52
56
41
69
92
64
76
145
12
90
128
116
88
154
134
149
9
7
18
25
24
110
153
(a)
160
159
13
50
33
81
120
11
35
37
123
144
58
146
114
40
74
106
27
100
139
59
122
118
98
54
136
107
65
39
83
14
10
8
2
102
147
29
61
55
47
108
95
79
142
97
141
127
138
121
15
23
3
18
66
62
57
132
20
115
84
43
85
19
114
55
45
142
118
96
151
111
95
96
124
132
156
135
89
157
137
67
152
103
60
117
155
156
139
144
14
155
30
54
32
31
62
71
112
133
135
21
80
116
126
65
131
149
84
134
41
127
100
88
98
44
69
81
122
146
143
113
83
136
90
154
9
13
66
64
57
109
20
38
52
104
129
7
29
34
70
63
105
73
99
12
102
61
79
108
93
141
147
148
130
89
36
115
78
22
24
107
151
91
37
123
121
87
86
1
16
72
157
138
67
77
35
94
106
153
159
125
33
74
51
39
49
11
28
40
110
97
117
5
27
45
47
17
82
119
158
25
68
46
48
92
101
128
140
8
150
120
23
50
10
4
85
58
42
76
2
6
15
43
26
3
56
59
53
75
160
137
152
145
103
60
(b)
Bild 5. Partitionierung eines zufällig generierten Graphen mit 160 Knoten ergibt: (a) 52 Microthreads
bei optimistischen Kommunikationskosten; (b) 39 Microthreads bei realistischeren Kommunikationskosten
Kompromiß zwischen Parallelismus und Lokalität
sehr gut zu sehen ist. Bild 3 partitioniert den Graphen unter der Annahme optimistischer Kantengewichte. Hier entschied der Partitionierungsalgorithmus das Maximum an Parallelität beizubehalten, indem alle Multiplikationen parallel ausgeführt und
die abhängigen Additionen in 9 Microthreads zusammengefügt werden.
Im Gegensatz dazu ist in Bild 4 zwar der gleiche Graph, aber realistischere Kommunikationskosten angenommen. Diesmal hat der Algorithmus etwas Parallelität zu Gunsten der Lokalität geopfert.
Hier wird jedes der 9 Resultate der Matritzenmultiplikation in einem eigenen Microthread berechnet.
Die Bilder 3 und 4 zeigen also die Fähigkeit des
Algorithmus die Struktur eines regelmäßigen Datenflußgraphen zu erforschen und nutzbar zu machen.
Um zu sehen wie der Algorithmus mit unregelmäßigen Datenflußgraphen umgeht, wurde der Partitionierungsalgorithmus mit zufällig erzeugten Datenflußgraphen getestet. Die Bilder 5 (a) und (b) zeigen
die Partitionierung eines zufällig erzeugten Graphen
mit 160 Knoten. Abbildung 5 (a) geht wiederum von
optimistischen Kommunikationskosten aus, und der
Algorithmus produziert 52 Microthreads. Bei realistischen Kommunikationskosten (Abbildung 5 (b))
werden 39 Microthreads erzeugt.
Die Kommunikationskosten müssen nicht genau abgeschätzt werden. In Bilder 3 und 5 (a) war
ILK MK N sI YJZ#[#Z#K \Z I c Z#Md
Is[#h(iji I A3 tuL4f
d.h. die Kosten für eine Nachricht waren den Kosten für eine Rechenoperation gleichgesetzt. Das
Partitionierung-Programm erzeugte dieselbe Graphzerlegung wie in Bilder 4 und 5 (b) für alle Werte im
Bereich
vw
vww
I Jxzy I K MK N I [#hiji |{ I A3
4
Dynamische Verteilung
4.1
Anpassung von COMA für SDAARC
Wie in Abschnitt 1 und 2 angesprochen, basiert
SDAARC auf der COMA Technologie. COMAs
(z.B. [5] oder [14]) implementieren einen transparent verteilten, gemeinsamen Adreßraum für parallele Prozessoren. Datenblöcke bewegen sich von
lokalen Speichern zu lokalen Speichern als Antwort auf Lese- und Schreiboperationen. Wie bei allen Cache-Technologien, repräsentiert diese Strategie ein Glücksspiel um Lokalität: Solange die an-
genommene Lokalität besteht, stehen die Gewinnchancen gut, daß das Datum welches von einer Site
benötigt wird, dort in naher Zukunft wieder benötigt
wird. Ist die Annahme bezüglich der Lokalität falsch,
kann es passieren, daß Daten zwischen Sites unnötiger Weise hin und her geschaufelt werden (PingPong Effekt).
Der erste Eindruck von SDAARC vermittelt die
Vorstellung, daß durch die Verbindung eines jeden
Threads mit einem Datenobjekt wiederum Objekte
entstehen, die man durch COMA unter den Attraction Memory Sites verteilen lassen könnte. Tasks für
jeden Prozessor entsprechen den Thread-Objekten,
die sich momentan in seinem lokalen Speicher befinden und könnten so geschedult werden. Man muß
nicht lange suchen, bis man solche Objekte finden
kann: in der Literatur zu Multithreaded“ (Mehrfädi”
gen) Architekturen existiert zu jedem Thread ein
Frame, der die Argumente und Rückgabeadressen
des entsprechenden Threads beinhaltet. Diese Frames ähneln stark den Stack-Frames in konventionellen (sequentiellen) Architekturen, bis auf den Unterschied, daß diese nicht in einem Stack organisiert sind. Statt dessen werden die Frames wirksam
in einem verteilten, gemeinsamen Heap gespeichert.
Gewöhnlich können mehrere Threads einen Frame
teilen [12] [2], doch die jüngere Literatur merkt an,
daß Performancesteigerungen zu erreichen sind, falls
jeder Thread einen eigenen Frame, genannt Framelet,
besitzt [1].
Hat man ein Datenobjekt für jeden Thread gefunden und erlaubt die Verwendung der COMA Technologie um sowohl die Berechnung als auch die
Daten zu verteilen, ist offensichtlich weitere Optimierung möglich. So haben wir nun ein Konzept,
in dem nicht nur Daten wandern können, um sich
der Programmaufteilung anzupassen, sondern in dem
sich die Verteilung des Programms simultan zur Datenverteilung anpaßt. Dies stellt somit eine Lösung
des Ping-Pong Effekts dar. In einer konventionellen
COMA gibt es keinen effektiven Weg für die Daten
sich einer schlechten Programmverteilung anzupassen: wird ein Datenblock von zwei Sites gleichzeitig
benötigt, muß dieser Block zwischen diesen hin und
her wandern. Im Gegensatz dazu ist es in SDAARC
möglich, daß die konkurrierenden Berechnungen auf
die selbe Site verteilt werden.
4.2
Die Broker und das Protokoll
Die Broker in SDAARC sind eine Erweiterung der
Cache-Kohärenz-Controller aus der COMA Literatur. Sie sind verantwortlich für den Netzwerkverkehr,
den zugehörigen Prozessor mit Frames (Threads)
zu versorgen und sicherzustellen, daß der transparent verteilte, gemeinsame Adreßraum konsistent
und kohärent bleibt.
Entsprechend einer herkömmlichen COMA, befolgen die Broker ein Cache-Kohärenz-Protokoll.
Durch die Verbindung von Berechnung und Daten
ist es möglich das Protokoll im Vergleich zu anderen
COMAs wesentlich einfacher zu gestalten. In diesem Protokoll [9] können Objekte in einem von fünf
Zuständen sein: Exklusiv, Cloned, Original, Leaving
oder Invalid (ECOLI). Dies kann mit dem weit verbreiteten SMP (nicht-COMA) MESI (Modified, Shared, Exclusive und Invalid) Protokollen oder dem 7
Zustände COMA Protokoll aus [6] verglichen werden.
Der gemeinsame Adreßraum in SDAARC ist in drei
Bereiche aufgeteilt. Entsprechend einer herkömmlichen Harvard Architektur, gibt es Daten- und Berechnungsbereiche. Zusätzlich existiert ein dritter
Bereich für Frames, um eine spezielle, optimale
Handhabe der wichtigen Datenobjekte zu erlauben.
4.3
tet. Wird ein Objekt in eine Menge eingefügt die
schon voll ist, muß ein anderes Objekt abwandern um Platz zu schaffen.
2. Ist der Broker untätig, kann er Mengen identifizieren, die fast voll sind und spontan Objekte
von diesen Mengen ausweisen.
Entsprechend gibt es zwei Gruppen von anziehenden
Verteilungsereignissen:
1. Berechnet ein Thread ein Argument für einen
anderen Frame, der sich auf einer anderen Site befindet, kann der empfangende Broker entscheiden, ob er einfach das Argument akzeptiert
oder statt dessen den empfangenden Frame zu
der Site schickt, die das Argument sendet.
2. In SDAARC produziert das Laden oder Speichern eines Datums immer eine Bestätigung um
Synchronisation von Datenobjekten zu ermöglichen. Wenn Daten vom Datenbereich geladen
oder gespeichert werden, kann der Broker entscheiden, ob der komplette Datenblock zur Site
geschickt wird, die auf die Bestätigung wartet.
Verteilungsereignisse
Wie oben beschrieben, müssen die Broker die Balance zwischen den entgegengesetzten Forderungen
nach Parallelität und Lokalität finden (um die Kommunikationskosten zu reduzieren). Um dies zu erreichen, müssen diese eine Sammlung von mehr oder
weniger abhängigen Threads und Datenobjekten zusammenfügen. Das Ziel ist stets die kürzeste Laufzeit und nicht notwendigerweise ein gleichmäßiges
Load-Balancing zu realisieren. Tasks sollten lediglich auf so viele Prozessoren verteilt werden, wie es
auch effizient genutzt werden kann (insbesondere in
Multitasking Umgebungen).
Um diesen Spagat zu erreichen, definieren wir eine Anzahl von Kräften, die das Wandern von Objekten und Threads bewirken. Diese Kräfte fallen in
zwei Kategorien: abstoßende Kräfte, verteilen Objekte und maximieren somit Parallelität (eventuell
auf Kosten der Lokalität); wohingegen anziehende
Kräfte verwandte Objekte zusammenbringen und die
Lokalität maximieren (eventuell auf Kosten der Parallelität). Diese Kräfte wirken zu präzise definierten
Verteilungsereignissen. Wenn diese Ereignisse eintreten, treffen die Broker die Entscheidung welche
Objekte wandern und wohin sie wandern.
Es gibt zwei abstoßende Verteilungsereignisse:
1. Angenommen die Attraction-Speicher sind
mengenassoziativ: Jedes Objekt ist statisch auf
eine Menge abgebildet, die eine kleine, konstante Anzahl (z.B. 4 oder 8) von Objekten beinhal-
5
Zusammenfassung
In diesem Beitrag wurde ein hybrides System zur
Partitionierung und Verteilung von Daten- und Berechnungslast in einem parallelen verteiltem System vorgestellt. Feingranulare Entscheidungen werden hier zur Compilezeit getroffen: Ein Programm
wird in einen Datenflußgraphen übersetzt, aus dem
durch einen heuristischen, gierigen Packalgorithmus
Microthreads generiert werden. Grobgranulare Entscheidungen werden zur Laufzeit getroffen: Jedem
Prozessor ist ein Broker an die Seite gestellt, dessen Aufgabe es ist: erstens, ein Cache-KohärenzProtokoll auszuführen, welches einen transparenten
verteilten, gemeinsamen Adreßraum implementiert;
und zweitens, aus dem lokalen Anteil gemeinsamer
Frames genau solche, basierend auf den Informationen über die dynamische Last, auszusuchen, die für
den lokalen Prozessor geeignet sind.
Dieses Konzept, genannt SDAARC (SelfDistributing Associative ARChitecture) ist eine
Erweiterung der COMA (Cache Only Memory
Architecture) Techniken. Während sich COMAs
mit dem Bereitstellen eines verteilten gemeinsamen
Speichers begnügen, geht SDAARC weiter und
bezieht die automatische Verteilung der Berechnung
mit ein.
Literatur
[1]
A NNAVARAM, M. ; NAJJAR, W. A.: Comparison of Two Storage Models in Data-Driven
Multithreaded Architectures. In: Eighth IEEE
Symposium on Parallel and Distributed Processing (SPDP). New Orleans, LA : IEEE Computer Society Press, Oktober 1996, S. 122–129
[2]
C ULLER, D. E. ; G OLDSTEIN, S. C. ; S CHAU SER, K. E. ; VON E ICKEN , T.: TAM — A Compiler Controlled Threaded Abstract Machine.
In: Journal of Parallel and Distributed Computing, Special Issue on Dataflow, 1993
[3]
C ULLER, D. E. ; K ARP, R. ; PATTERSON, D. ;
S AHAY, A. ; S CHAUSER, K. E. ; S ANTOS, E. ;
S UBRAMONIAN, R. ; VON E ICKEN, T.: LogP:
Towards a Realistic Model of Parallel Computation. In: Proc. of Fourth ACM SIGPLAN
Symp. on Principles and Practice of Parallel
Programming. San Diego, CA, Mai 1993
[4]
D ENNEULIN, Y. ; NAMYST, R. ; M ÉHAUT,
J.-F.:
Architecture virtualization with
mobile threads.
In: Parallel Computing (ParCo’97)
(1997), September.
–
<http://www.ens-lyon.fr/
˜rnamyst/ps/parco97.ps.gz>
[5]
[6]
[7]
[8]
[9]
H AGERSTEN, E. ; L ANDIN, A. ; H ARIDI, S.:
DDM — A Cache-Only Memory Architecture.
In: IEEE Computer 25 (1992), Nr. 9, S. 44–54
H ARIDI, S. ; H AGERSTEN, E.: The Cache Coherence Protocol of the Data Diffusion Machine. In: Proceedings of the PARLE 89 Bd. 1,
Springer-Verlag, 1989, S. 1–18
K LANG, M.: Hierarchische Zerlegung von Datenflußgraphen für mehrfädige Architeckturen.
Fachbereich Informatik, Frankfurt am Main,
Johann Wolfgang Goethe Universität, Diplomarbeit, Oktober 1997
M OORE, R. ; K LAUER, B. ; WALDSCHMIDT,
K.: Compiler Technology for Two Novel
Computer Architectures. In: 14th ITG/GIFachtagung Architektur von Rechensystemen
1997 (ARCHS ’97).
Rostock, Germany,
September 1997. –
<http://www.ti.
informatik.uni-frankfurt.de/
Papers/Adarc/rostock.pdf>
M OORE, R. ; K LAUER, B. ; WALDSCHMIDT,
K.: Automatic Scheduling for Cache Only
Memory Architectures. In: Third International
Conference on Massively Parallel Computing
Systems (MPCS ’98).
Colorado Springs,
Colorado, April 1998. – <http://www.
ti.informatik.uni-frankfurt.de/
Papers/Adarc/colosprings.pdf>
[10] M OORE, R. ; K LAUER, B. ; WALDSCHMIDT,
K.: A Combined Virtual Shared Memory and
Network which Schedules. In: International
Journal of Parallel and Distributed Systems
and Networks 1 (1998), Nr. 2, S. 51–56.
–
<http://www.ti.informatik.
uni-frankfurt.de/Papers/Adarc/
barcelona.pdf>
[11] M OORE, R. ; Z ICKENHEINER, S. ; K LAUER, B.
; H ENRITZI, F. ; B LECK, A. ; WALDSCHMIDT,
K.: Neural Compiler Technology for a Parallel
Architecture. In: International Conference on
Parallel and Distributed Processing Techniques
and Applications (PDPTA ’96). Sunnyvale,
CA, August 1996. – <http://www.ti.
informatik.uni-frankfurt.de/
Papers/Adarc/camready.pdf>
[12] N IKHIL, R. S.: A Multithreaded Implementation of Id using P-RISC Graphs. In: Proceedings of the Sixth Annual Workshop on Languages and Compilers for Parallel Computing.
Portland, Oregon : Springer Verlag LNCS 768,
August 1993, S. 390–405
[13] PATTERSON, D. A.: Microprocessors in 2020.
In: Scientific American Special Issue: The
Solid-State Century 8 (1997), Nr. 1, S. 86–88
[14] S AULSBURY, A. ; W ILKINSON, T. ; C ARTER,
J. ; L ANDIN, A.: An Argument For Simple
COMA. In: First IEEE Symposium on High
Performance Computer Architecture. Rayleigh,
North Carolina, Januar 1995, S. 276–285
[15] S TENSTR ÖM, P. ; J OE, T. ; G UPTA, A.: Comparative Performance Evaluation of CacheCoherent NUMA and COMA Architectures.
In: Proceedings of the 19th Annual International Symposium on Computer Architecture.
Gold Coast, Australia, Mai 1992, S. 80–91
[16] T HITIKAMOL, K. ; K ELEHER, P.: Thread
Migration and Communication Minimization
in DSM Systems. In: Proceedings of the
IEEE
87 (1999), März, Nr. 3, S. 487–
497. –
<http://mojo.cs.umd.edu/
papers/ieee98.pdf>
Herunterladen