[informatik-fachberichte] parallele implementierung funktionaler programmiersprachen volume 232 ||...
TRANSCRIPT
Kapitel7
Einteilung Prozesse
• In parallele
Die im letzten Kapitel anhand der abstrakten Interpretationen der Basisfunktionen, Konstruktoren und Kombinatoren hergeleiteten "evaluation transformer" liefern Informationen iiber die in einem Kombinatorprogramm enthaltene implizite Par all eli tat.
Prinzipiell kann jeder Teilausdruck, fiir den sich wahrend der Programmausfiihrung ein von ~o verschiedener Auswerter ergibt, parallel ausgewertet werden. Eine solche Implementierung der parallelen Auswertung eines funktionalen Programms ist aber nicht unbedingt optimal, da die parallele Auswertung eines Teilausdruckes immer einen zusatzlichen Organisationsaufwand erfordert. Der Teilausdruck und die Informationen, die zu seiner Auswertung notwendig sind, miissen als Nachricht kodiert werden, zu einem anderen Prozessorelement transferiert und dort dekodiert werden. In analoger Weise muB schlieBlich das Ergebnis der Teilberechnung zuriicktransportiert werden. Ein Teilausdruck, der parallel ausgewertet wird, sollte also so komplex sein, daB der Gewinn, der durch die parallele Ausfiihrung erreicht wird, groBer ist als der Mehraufwand, mit dem die Parallelausfiihrung verbunden ist.
Dieser Mehraufwand wird haufig mit Kommunikationskosten bezeichnet, obwohl die eigentlichen Kommunikationskosten, also die Zeiten fiir die Ubertragung von Nachrichten zwischen Prozessorelementen, vernachlassigbar klein sind. Daher werden wir den Mehraufwand Verteilungskosten nennen.
Zur Entscheidung, ob ein Teilausdruck parallel ausgewertet werden solI oder nicht, muB also eine KomplexWitsabschatzung des Ausdruckes vorgenommen werden. Da die vorhandene Parallelitat natiirlich vom Auswerter eines Ausdruckes abhangt, ist letztendlich erst zur Laufzeit zu erkennen, welche Teilausdriicke tat-
R. Loogen, Parallele Implementierung funktionaler Programmiersprachen© Springer-Verlag Berlin Heidelberg 1990
190 KAPITEL 7. EINTEILUNG IN PARALLELE PROZESSE
sachlich parallel ausgewertet werden k6nnen. Die Entscheidung iiber die Parallelauswertung sollte aber zur Ubersetzungszeit soweit vorbereitet werden, daB sie zur Laufzeit keine zusatzliche Zeit erfordert.
Wir beschreiben in diesem Kapitel eine Transformation von Kombinatorsystemen in sogenannte parallelisierte K ombinatorsysteme, in den en die Stellen, an denen eine Parallelauswertung m6glich ist und sinnvoll erscheint, durch ein spezielles syntaktisches Konstrukt angezeigt werden. Motiviert wurde dieser Ansatz durch die Arbeiten von Hudak und Goldberg [Hudak, Goldberg 85ajb], die einen ahnlichen Algorithmus zur Erzeugung serieller Kombinatorsysteme, welche im wesentlichen den hier betrachteten parallelisierten Kombinatorsystemen entsprechen, beschreiben.
Serielle Kombinatoren bestimmen die Granularitat der Parallelitat. Jeder Teilausdruck, fiir den eine Parallelauswertung gewinnbringend sein kann, wird als Kombinator definiert. Parallele Prozesse entsprechen damit immer Kombinatoraufrufen. Weiterhin enthalt der Rumpf eines seriellen Kombinators keinen Teilausdruck, fiir den eine Parallelauswertung lohnend sein kann, der aber nicht als solcher gekennzeichnet ist.
Wir beginnen mit der Beschreibung der erweiterten Syntax und Reduktionssemantik parallelisierter Kombinatorsysteme.
7.1 Parallelisierte Kombinatorsysteme
Die Ausdriicke, die als Riimpfe parallelisierter Kombinatoren auftreten, sind applikative Ausdriicke, die ein spezielles syntaktisches Konstrukt enthalten k6nnen, das M6glichkeiten zur Parallelauswertung anzeigt.
7.1.1 Definition Sei rg eine Rangfunktion.
Die Menge
.ParEXPrg = (ParExp;g It E Typ(S, D))
der parallelisierten applikativen A usdriicke iiber rg ist die kleinste Typ( S, D)sortierte Mengenfamilie mit:
1. - 9. analog zu der Definition der flachen applikativen Ausdriicke (5.4.1) und
10. Sei p E IN, Yi E Loct• mit ti E Typ(S, D) (1 ~ i ~ p).
Falls Fi(eil, ... ,eir.) E ParExp;~ mit Fi E Def(rg) und rg(Fi) = ri,
falls e E ParExp;g mit (t E Typ(S, D)) und eVi E Evsett fUr 1 ~ i ~ p, dann ist auch
7.1. PARALLELISIERTE KOMBINATORSYSTEME
let par Yl=F1(ell, ... ,elrJ ifevl and and YP = Fp(epl,"" epr ) if evp
P t in e E ParExPrg'
191
Das neu hinzugekommene letpar-Konstrukt zeigt explizit Moglichkeiten zur Parallelausfiihrung an. Teilausdriicke, die unter bestimmten Auswertern parallel ausgewertet werden konnen, werden aus dem Gesamtausdruck herausabstrahiert. Sie werden durch Applikationen von - wenn notig neu definierten - Kombinatoren F1 , ... , Fp reprasentiert. Parallele Prozesse entsprechen also Kombinatorapplikationen. Dies ermoglicht eine kompakte Beschreibung der Prozesse durch den Kombinatornamen und die Argumentliste.
Die Parallelausfiihrung von Teilausdriicken hangt im allgemeinen von dem Auswerter des Gesamtausdruckes abo Die Kombinatorapplikation Fi (eil, ... , eir.) solI nur dann parallel ausgefiihrt werden, wenn der aktuelle Auswerter des Gesamtausdruckes grofier ist als der im letpar-Konstrukt gegebene Auswerter eVi. Die parallelen Teilprozesse werden im Gesamtausdruck durch die lokalen Variablen Yl, ... , YP ersetzt. Der verbleibende Ausdruck e beschreibt den Teil der Berechnung, der sequentiell ausgefiihrt werden solI. Bei der Referenzierung der in e enthaltenen Variablen Yi (1 ::; i ::; p) erfolgt eine Synchronisation der sequentiellen Hauptrechnung mit dem i-ten parallelen Teilprozefi.
Das entstehende Prozefisystem ist hierarchisch. Die Ausfiihrung eines parallelisierten Kombinatorsystems startet mit der Ausfiihrung des Hauptprogrammausdruckes. Letpar-Ausdriicke fiihren zur Aktivierung von Teilprozessen, die auf anderen Prozessorelementen ausgefiihrt werden konnen. Die Ausfiihrung von parallelen Teilprozessen kann erneut zur Aktivierung paralleler Prozesse fiihren. Nach Beendigung eines Prozesses wird das Resultat an die Stellen iibermittelt, an denen es benotigt wird.
Die Definition parallelisierter Ausdriicke ist sehr allgemein gehalten. Es ist eine beliebige Schachtelung der ausdrucksbildenden Konstrukte zugelassen, die in dieser Allgemeinheit nicht notwendig ist. So wird das letpar-Konstrukt i.a. nicht in der Argumentposition einer Applikation auftreten.
Parallelisierte Kombinatorsysteme und -programme sind solche, in denen parallelisierte Ausdriicke als Kombinatorriimpfe und als Hauptausdruck auftreten.
7.1.2 Definition Ein parallelisiertes Kombinatorprogramm
(F;e)
vom Typ s E SUD besteht aus einem parallelisierten (flachen) Kombinatorsystem
192 KAPITEL 7. EINTEILUNG IN PARALLELE PROZESSE
mit r = 1, Fi E Funt • mit ti E Typ(S, D) und t ..
ei E ParEXPr~ mit free (ei) ~ {xi, ... ,X~JU{FI, ... ,Fr},
wobei rg : { {FI' ·F; , Fr } : ~} (1 ~ i ~ r) und einem parallelisierten
applikativen Ausdruek
e E ParExp~g mit free(e) ~ {FI , ... , Fr }.
Die niehtdeterministische Reduktionssemantik parallelisierter Kombinatorsysterne entsprieht derjenigen flaeher Kombinatorsysteme, denn die Semantik des letpar-Konstruktes entsprieht der des let-Konstruktes. Aueh bei der Annotierung wird das letpar-Konstrukt wie das let-Konstrukt behandelt. Das let parKonstrukt beeinfluBt allerdings die Reduktionsstrategie, wie wir im naehsten Kapitel verdeutliehen werden. Zuvor besehreiben wir noeh den Algorithmus zur Erzeugung von letpar-Ausdriieken in Kombinatorprogrammen.
7.2 Der Parallelisierungsalgorithmus
Zur Erlauterung der Vorgehensweise bei der Erzeugung parallelisierter Kombinatorsysteme diskutieren wir zunaehst ein einfaehes Beispiel. Sei
ein zu parallelisierender Ausdruek, wobei f eine zweistellige Basisfunktion seL Da alle Basisfunktionen strikt interpretiert werden, ist es prinzipiell moglieh, die Argumentausdriieke el und e2 parallel auszuwerten, d.h. einen der beiden Ausdriieke auf einem anderen Prozessor auszufiihren. 1m folgenden bezeiehne
• Ti(exp) die Zeitkosten fiir die Ausfiihrung von exp auf i Prozessorelementen und
• Vi(exp) die Verteilungskosten, d.h. den Mehraufwand, der auf Prozessorele-ment i geleistet werden muB, bei Parallelausfiihrung von expo
Dabei nehmen wir zur Vereinfaehung an, daB geniigend Prozessoren vorhanden sind und daB jedes Prozessorelement mit jedem anderen direkt Naehriehten austausehen kann.
Wird etwa der Beispielausdruek e auf Prozessor 1 ausgefiihrt und die Auswertung von e2 naeh Prozessor 2 verlagert, so ergeben sieh, grob gesehen, folgende A usfiihrungszeiten:
TI (e) = TI(ed + TI(e2) + T(f) und T2(e) = VI(e2) + max{TI(ed, T2(e2) + V2(e2)} + T(f).
7.2. DER PARALLELISIERUNGSALGORITHMUS 193
Dabei steht
- fUr die Kodierung von e2 in eine Nachricht und die Versendung der Nachricht und
- fUr das Empfangen und Dekodieren des Resultates von e2
und
- fUr das Empfangen der Nachricht, die e2 enthalt, die Dekodierung dieser Nachricht sowie
- die Kodierung des Resultates von e2 nach Beendigung der Ausfiihrung und die Versendung der Antwortnachricht.
Damit die Parallelauswertung einen Gewinn bringt, sollte
gelten. Dies ist gleichbedeutend mit
d.h. es soUte V1(e) < T1(e2) und V1(e) + V 2(e) < T1(el)
gelten. Beide Ausdriicke miissen also eine gewisse Komplexitat haben. Damit
minimal wird, soUte zudem T1(e2) < T1(et) sein, d.h. es ist giinstiger, den weniger komplexeren Teilausdruck auf einem anderen Prozessorelement ausfUhren zu lassen.
Zur Parallelisierung wird somit neben den Striktheitsinformationen ein Komplexitiitsmap fUr Ausdriicke benotigt, das die Zeit, die zur Ausfiihrung eines Ausdruckes benotigt wird, abschatzt. Eine exakte Bestimmung von Ausfiihrungszeit en beliebiger Ausdriicke ist natiirlich nicht moglich. Ein solches Komplixitatsmafi wird i.a. auf Heuristiken beruhen. Es kann natiirlich auf eine spezielle Zielarchitektur zugeschnitten werden, wenn man die Abbildung der Ausdriicke in Maschinencode untersucht und Zeiten fiir einzelne Maschinenbefehle oder bestimmte Maschinencodesequenzen beriicksichtigt. Auch die Verteilungskosten sind von der Zielmaschine abhangig.
194 KAPITEL 7. EINTEILUNG IN PARALLELE PROZESSE
Das strenge sprachorientierte 'top-down'-Vorgehen kann an dieser Stelle also nicht ohne weiteres fortgesetzt werden. Bei der Aufteilung des funktionalen Programmes in parallele Prozesse sind Informationen iiber die Zielarchitektur notwendig. Bereits bei den obigen Abschatzungen gingen bestimmte Vorstellungen iiber die Organisation der parallelen Ausfiihrung auf der Maschinenebene ein. Es erfolgt hier ein RiickfluB von Informationen der maschinennahen Implementierung in die sprachliche Zwischenebene der parallelisierten Kombinatorsysteme.
1m folgenden set zen wir voraus, daB wir ein geeignetes KomplexitatsmaB fiir Ausdriicke sowie eine Abschatzung der Verteilungskosten zur VerfUgung haben. Das KomplexitatsmaB bezeichnen wir mit
complexity: AppExp -+ Rt
und distribution-costs E R bezeichne die Abschatzung der durchschnittlichen Verteilungskosten. Als weitere Eingaben benotigt der Parallelisierungsalgorithmus natiirlich das mit Annotationen versehene zu parallelisierende Kombinatorprogramm.
Wir beschreiben zunachst eine Parallelisierungsfunktion fiir annotierte Ausdriicke eines Kombinatorprogramms n.
Die Parallelisierungsfunktion erhalt als Eingabe neben dem annotierten Ausdruck ein Kennwort zur eindeutigen Bezeichnung neu zu definierender Kombinatoreno Als Ausgabe erhalt man ein Paar, dessen erste Komponente der transformierte Ausdruck ist, aus dem die Teilausdriicke, fUr die eine Parallelauswertung sinnvoll erscheint, herausabstrahiert sind. Solche Teilausdriicke sind durch Applikationen neu definierter Kombinatoren ersetzt, die in der zweiten Komponente gegeben sind. In folgender Definition bezeichne Comdef wie in Kapitel 5 die Menge aller Kombinatordefinitionsgleichungen und ParExp die Menge aller parallelisierten applikativen Ausdriicke.
7.2.1 Definition Sei (n, e, (AN(k,e), AN(R,e) , ANrk,e»)} ein annotiertes Kombinatorprogramm. Unter Benutzung eines KomplexitatsmaBes complexity und einer Abschatzung der Verteilungskosten dc (distribution costs) definieren wir die Funktion
par = parR: FExPR x IN* -+ ParExp x P( Comdef).
Die Komponentenfunktionen von parR bezeichnen wir mit parI und par2.
1. parR (ean ) := (e, 0), falls complexity (e) < dc.
Dieser Fall trifft insbesondere fUr nicht-zusammengesetzte Ausdriicke zu.
t lR bezeichnet die Menge der reellen Zahlen.
7.2. DER PARALLELISIERUNGSALGORITHMUS 195
2. Ansonsten erfolgt die Definition durch strukturelle Induktion uber den Aufbau der zusammengesetzten flachen applikativen Ausdrucke. Fur konditionale Ausdrucke gehen wir der Einfachheit halber von der kontextfreien Annotierung aus:
(a) par((if e then el else e2 fi)an, w) := ( if parI (ern, w.O) then parI (ern, w.1) else parI (e~n, w.2) fi,
par2(ean , w.O) U par2(ern, w.1) U par2(e~n, w.2))
(b) par((case e of CI(Yll,.··,Ylml): eli ... i Ck(Ykl, ... , Ykm,,) : ekesac )an, w)
:= (case parl(ean,w.O) of CI(Yll, ... , Ylml) : parI (ern , w.1)i
esac,
par2(e, w.O) U U7=1 par2(ej, w.j))
(c) par(let YI = el and ... and Yk = ek in e, w) := ( let par Yil = F w.i l ( var ill, ... , var il n'l) if ev i l
and and Yi, = FW.i, (vari,l, . .. , vari,n,,) if eVi, in let Yh = eXPiI and ... and Yjm = eXPjm in parl(e,w.O), {Fw.h( varhl,···, varhnh) = parI (eh, w.h) I
hE {1, ... , k} mit complexity(eh) > de}
U par2(e, w.O) U U7=1 par2(el, w.l)), wobei gilt:
• {i l , ... ,ill n {it, ... ,jm} = 0 und {il, ... ,il}U{jl, ... ,jm} = {l, ... ,k}
• {il, ... ,il}:= {h E {l, ... ,k} I complexity(en) > de /\ 3~ E Evset : EThS(e)(~) > ~o}
Dabei sei e = let YI = el and ... and Yk = ek in e und ETCS(e) bezeichne den kontextsensitiven 'evaluation transformer' von e, der durch ANn(e) gegeben ist.
• eVil. := min{~ E Evset I EThS(e)(~) > ~o}, • {varhl' ... ' varhnh} := free(eh) n (Ary U Loc) fur 1 :::; h :::; ktt
{ ejh falls complexity(ejh) < de }
• eXPjh:= FW.jh(varjhl, ... ,varjhn3h) sonst
mit h E {1, ... , m}.
ttZur Vereinfachung verzichten wir auf eine Umbenennung lokaler Variablen zu Argumentvariablen, die genau genommen in den Kombinatordefinitionen vorgenommen werden mull.
196 KAPITEL 7. EINTEILUNG IN PARALLELE PROZESSE
(d) Sei, E n u r mit Stelligkeit k.
par(,(el, ... , ek), w) := ( let par Yw.i l = F w.il ( var ill, ... , var il n'l) if eVil
and and Yw.i , = F w.i , (var i,l, ... , var i,n,,) if eVi, in ,( eXPI, ... , eXPk), U7=1 par2(ej,w.j) U {Fw.h(varhl, ... ,varhnh) =parl(eh,w.h) I
hE {I, ... , k} \ {io}, eomplexity(eh) > de}),
wobei
• {io,il, ... ,il}:= {h E {I, ... ,k} I eomplexity(eh) > de " 3~ E Evset : ETh(J)(~) > ~o},
io sei minimal mit complexity ( eio) ~ complexity ( eiJ) fUr alle 1 ~j ~ m
• {varjl,'''' varjnJ := /ree(ej) n (Arg U Loe), j E {I, ... , k}
• eViJ := min{~ E Evset I ETiJ (,)(~) > ~o} und
{ Yw.j fallsjE{il, ... ,il},
• ex .'= parl(ej,w.j) falls j = io, PJ • ej falls complexity ( ej) < dc,
Fw.i(varjl, ... ,varjnJ ) sonst.
(e) Sei F E {FI , ... , Fr } mit Rang k und Rumpf eF in R. ETCS(F( el, ... , ek)) sei der kontextsensitiven 'evaluation transfor-mer' von F bzgl. der Applikation F( el, ... , ek). Dann gilt:
par(F(el, ... , ek), w) := (letpar Yw.i l = FW ' il (varill, ... , variln'l) if eVil
and Yw.i, = F w.i, ( var i,l, ... , var i,ni, ) if eVi, in F( eXPI,"" eXPk), {Fw.h( varhl,···, varhnh) = parI (eh, w.h)
I h E {I, ... , k} \ (parset \ {iI, ... , il}), complexity ( eh) > de}
U U7=1 par2(ej, w.j) ),
wobei
• parset := {j E {I, ... , k} I complexity ( ej) > de " 3~ E Evset : ETCS(F(el, ... , ek))(~) > ~o}
7.2. DER PARALLELISIERUNGSALGORITHMUS
parset falls complexity(eF) > dc, parset \ {jo}
falls complexity( e F) ~ dc und jo E parset ist minimal mit complexity ( ejo) ~ complexity( ej) fUr alle j E parset.
197
• eVi, := min{~ E Evset I ETi:(F(el, ... ,ek»(~) > ~o} (1 ~ j ~ I)
• {varhl, ... , Varhnh} := free(eh) n (Arg U Loe) (1 ~ h ~ k) und
• ex .. = parl(ej,w.j) fallsjEparset\{il, ... ,il}, { Yw.j falls j E {it, ... , ill,
PJ • ej falls complexity(ej) ~ dc, Fw.j( var jl, ... , var jn,) sonst.
(f) par(ap(eO,el, ... ,ek» := (letpar Yw.i] = F w.i] (var i] , ... , var i] n , ]) if eVil
and and Yw.i, = Fw.i,(vari,l, ... ,vari/n.) ifevi, in ap(expo, ... ,exPk), {Fw.j ( var jl, ... , Varjn) = parI (ej, w.j)
I j E {I, ... , k} \ (parset \ {i l , ... , il}), complexity(ej) > dc} U U;=l par2 (ej, w.j) )
wobei
• parset := {j E {O, ... , k} I complexity ( ej) > dc /\ 3~ E Evset : ET?(ap(eo, ... , ek»(~) > ~o}
Dabei bezeichnet ETCS(ap(eo, ... , ek» den kontextsensitiven 'evaluation transformer' von ap(eo, ... ,ek).
• {i l , ... , ill := parset \ min{jo E parset I Vj: complexity(ejo) ~ complexity(ej)},
• {varjl' ... ' Varjn,} := free(ej) n (Arg U Loc) (1 ~ j ~ k), • eViJ := min{~ E Evset I ETi:(ap(eo, ... , ek»(~) > ~o}
(1 ~ j ~ I) und
Yw.j falls j E {i l , ... , ill, parI (ej, w.j) fUr j = min{jo E parset I
Vh : complexity(ejo) > complexity ( eh) },
ej falls complexity( ej) < dc, Fw.j(varjl, ... ,varjnJ ) sonst
198 KAPITEL 7. EINTEILUNG IN PARALLELE PROZESSE
Die Parallelisierung eines Ausdruckes nirnmt folgenden Verlauf: Zunachst wird die Komplexitat des Ausdruckes bestimmt. Gilt
complexity( e) < dc,
so braucht der Ausdruck nicht weiter untersucht zu werden, da eine Parallelausfiihrung von Teilausdriicken aufgrund der zu geringen Komplexitat nicht lohnt.
Anderenfalls, werden im Fall konditionaler Ausdriicke die Teilausdriicke parallelisiert. 1m Fall applikativer Ausdriicke - zu denen wir auch let-Ausdriicke zahlen - werden mit Hilfe des Komplexitatsmafies und mit Hilfe der kontextsensitiven 'evaluation transformer' der Applikation die Teilausdriicke bestimmt, fiir die bei gewissen Auswertern eine Parallelauswertung von Vorteil ist. Es wird jeweils Sorge getragen, daB einer der parallel auswertbaren Teilausdriicke als Teil der Hauptrechnung erhalten bleibt. Bei Kombinatorapplikationen kann dies auch der Rumpf des Kombinators sein. Fiir die Teilausdriicke, die gegebenenfalls parallel ausgewertet werden, werden neue Kombinatoren definiert, deren Rumpf der parallelisierten Form dieser Teilausdriicke entspricht. Die Definition redundanter Kombinatoren, deren Rumpf einer Kombinatorapplikation entspricht, kann dabei natiirlich vermieden werden. Bei der Ersetzung 'redundanter' Kombinatorapplikationen andert sich allerdings der Berechnungsort der Argumente der Kombinatorapplikation, die den Rumpf des 'neu' erzeugten Kombinators bildet. Die Aktivierung der Argumente erfolgt nicht mehr an dem Ort, an dem der parallele Prozef3 ausgewertet wird, sondern an dem Ort, wo die Aktivierung des parallelen Prozesses stattfindet.
In der Definition neuer Kombinatoren weicht der hier beschriebene Algorithmus von dem in [Hudak, Goldberg 85a] gegebenen Algorithmus abo Wahrend wir die parallelisierte Form der Teilausdriicke als Rumpf der neu definierten Kombinatoren wahlen und damit die parallele Ausfiihrung von Teilprozessen der Teilausdriicke lokal halten, abstrahieren Hudak und Goldberg die parallelen Teilberechnungen auch aus den Kombinatorapplikationen. Dies fiihrt zu einer friiheren Aktivierung solcher Teilprozesse bei der Ausfiihrung des parallelisierten Kombinatorsystems, verschlechtert allerdings die Lokalitat der Teilprozesse, da diese nicht mehr von den Prozessen aktiviert werden, die ihre Ergebnisse benotigen, sondern unter Umstanden sogar zeitlich vor diesen Prozessen. Zur Erhaltung der Lokalitat haben wir den Ansatz gewahlt, parallele Teilberechnungen von parallelen Berechnungen lokal zu diesen zu halten. Der Grad der Parallelitat bleibt natiirlich erhalten.
Ob ein herausabstrahierter Teilausdruck tatsachlich parallel ausgefiihrt werden sollte, hangt vom Auswerter und 'evaluation transformer' des Gesamtausdruckes abo In obiger Definition wird eine Parallelauswertung zugelassen, sob aId sich ein
7.2. DER PARALLELISIERUNGSALGORITHMUS 199
von ~o verschiedener Auswerter fUr den Teilausdruck ergibt. An dieser Stelle kann eine Analyse der Komplexitat der Teilberechnung unter Einbeziehung des Auswerters eines Ausdruckes eine genauere Kontrolle der Granularitat der parallelen Prozesse ergeben. Die Komplexitat eines Teilausdruckes ist zwar vom Auswerter des Teilausdruckes unabhangig, aber die Komplexitat der von einem Teilausdruck initiierten Teilberechnung wird sehr stark vom Auswerter des Teilausdruckes beeinflufit. Natiirlich erfordern genauere Analysen einen grofieren Aufwand. Bei jeder Verfeinerung der Analysetechniken stellt sich letztendlich die Frage, in welchem Verhaltnis der Optimierungsgewinn zum Mehraufwand steht. Daher werden wir auf weitere Verfeinerungen des Parallelisierungsalgorithmus hier nicht eingehen.
Eine Besonderheit des obigen Algorithmus ist, daB nicht nur die Teilausdrucke, fUr die eine Parallelauswertung auf Grund der durch die 'evaluation transformer' gegebenen Informationen moglich ist, zur Definition neuer Kombinatoren fUhren, sondern aIle Teilausdriicke, deren Komplexitat eine Parallelausfiihrung lohnend erscheinen laBt. Dies zeigt eine weitere Quelle der Parallelitiit in parallelisierten Kombinatorsystemen. Nicht nur Kombinatorapplikationen, die im let parKonstrukt ausgezeichnet sind, fUhren zu parallelen Prozessen, sondern auch Kombinatorapplikationen, die 'strikte' Argumente in dynamisch zur Laufzeit entstehenden Applikationen sind bzw. als nicht-strikte Argumente verzogert ausgewertet werden. Welche Programmteile parallel ausgewertet werden, beschreiben wir detailliert im folgenden Kapitel durch eine deterministische Graphreduktionssemantik, die die Grundlage der im dritten Teil dieser Arbeit entwickelten Maschinenimplementierung bildet.
Die Transformation eines Kombinatorprogramms in ein parallelisiertes Kombinatorprogramm erfolgt also in folgender Weise:
1. Anhand der abstrakten Interpretation werden fUr alle applikativen Teilausdriicke des Kombinatorprogramms kontextsensitive "evaluation transformer" bestimmt.
2. Die Parallelisierungsfunktion liefert dann zu jedem annotierten Kombinatorrumpf einen parallelisierten Ausdruck und eine Menge neu definierter Kombinatoren.
3. Die Ersetzung der Kombinatorriimpfe durch die parallelisierten Ausdriicke und die Hinzunahme der neu definierten Kombinatoren ergibt das parallelisierte Kombinatorsystem.
4. Mittels der Annotationen des urspriinglichen Systems wird schlieBlich in einfacher Weise die Annotierung des parallelisierten Systems bestimmt.
200 KAPITEL 7. EINTEILUNG IN PARALLELE PROZESSE
7.2.2 Definition Sei ('R., e, AN (7i,e») mit
'R. = (Fi(xL . .. ,x~J = ei 11 ::; i ::; r)
und AN(7i,e):= (AN(k,e),AN(~,e),AN(k,e»)
ein annotiertes Kombinatorprogramm.
Dann hei6t
par('R.):= (Fi(xL ... ,x~J = parl(e~n,i) 11::; i::; m) U (U~=l par2(e~n, i)) U par2(ean, 0)
die Parallelisierung von 'R. (unter dem KomplexWitsmafi complexity und den Verteilungskosten dc).
(par('R.) , parI (ean , 0)) hei6t entsprechend die Parallelisierung von ('R., e) unter den gegebenen Annahmen.
Die Parallelisierung eines Kombinatorprogramms ist ein wohldefiniertes parallelisiertes Kombinatorprogramm. Wir verzichten hier allerdings auf einen formalen Beweis dieser Aussage. Die Superkombinatoreigenschaft bleibt bei der Parallelisierung erhalten.
Zum Abschlu6 dieses Kapitels geben wir eine Parallelisierung des Beispielprogramms zur Listensortierung an:
7.2.3 Beispiel Untersucht man die Riimpfe der Kombinatoren des Beispieles 5.2.6 bzw. 5.4.11 unter Beriicksichtigung der in Beispiel 6.2.5 gegebenen 'evaluation transformer' dieser Kombinatoren bzw. der kontextsensitiven 'evaluation transformer' der Kombinatorriimpfe, so ergeben sich sinnvolle Parallelisierungsmoglichkeiten eigentlich nur im Rumpf des Kombinators QSort. Die Kombinatoren Filter und Append sind eher sequentieller Natur, wahrend die Kombinatoren Tgeq und Tit von zu geringer Komplexitat sind.
Unter entsprechenden Vorgaben ist etwa folgende Parallelisierung des Beispielprogramms denkbar, bei der der Kombinator QSort wie folgt ersetzt wird:
PQSort(lintliBt) := case 1 of NIL: NIL;
CONS(YI, Y2) :
esac
letpar iii = PQSort(Filter (Tlt(Yt), Y2)) if 6 and ih = PQSort( Filter ( Tgeq(YI ), Y2)) if 6 in Append (jiI, CONS(YI, fh))
7.2. DER PARALLELISIERUNGSALGORITHMUS 201
Bei der Erzeugung dieses Kombinators wurde die Definition redundanter Kombinatoren fiir die parallelen Prozesse vermieden.
Auf die mogliche Parallelausfiihrung der Argumentausdriicke der Aufrufe von PQSort wurde verzichtet. Eine tatsachliche Parallelisierung wird stark von dem vorgegebenen Komplexitatsmafi bzw. den Verteilungskosten abhangen, iiber die wir hier keine Annahmen machen.