Universität Karlsruhe (TH) Forschungsuniversität · gegründet 1825 Software Engineering für moderne, parallele Plattformen 3. Parallelität in deklarativen Programmiersprachen Dr. Victor Pankratius Prof. Walter F. Tichy, Dr. Victor Pankratius, Dipl.-Inform. Frank Otto Fakultät für Informatik Lehrstuhl für Programmiersysteme Agenda • In den nächsten Vorlesungen: Überblick über Parallelisierungsansätze in verschiedenen Programmiersprachen • Zunächst Prinzipien aus deklarativen Programmiersprachen (logische / funktionale Sprachen) ÆMotivation: Æ Verstehen, wie hier parallelisiert wird Æ Weiterer Grund: Moderne (imperative) Sprachen greifen z.T. Konzepte aus mehreren unterschiedlichen Paradigmen auf. Wir wollen deren Ursprünge verstehen. • Anschließend in nächsten Vorlesungen: Ausführlichere Betrachtung ausgewählter Sprachen und Bibliotheken im Hinblick auf Parallelität Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 2 Logische Programmiersprachen Zur Erinnerung… • Verwenden logische Aussagen zur Durchführung von Berechnungen • Axiome: Aussagen, die als wahr angenommen werden; werden zum Beweis anderer wahrer Aussagen verwendet • Deklarativer Ansatz: In logischen Programmen wird nur Menge von Axiomen festgelegt, nicht aber wie die Ableitung anderer Aussagen genau zu erfolgen hat • Inferenzregeln bestimmen, wie Aussagen abgeleitet werden können • Eingaben für die Programme sind Anfragen (Behauptungen), für die ein Beweiser versucht, anhand der Axiome und Inferenzregeln deren Wahrheitswert zu bestimmen • Anwendungsbeispiele: Regelbasierte Systeme, Abfragesprachen in Datenbanken Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 3 Logische Programmiersprachen Zur Erinnerung… Beispiel: Prolog (1) • Verwendet Horn-Klauseln zur Darstellung von Aussagen B :- A1, A2, … , An Konsequenz (Kopf, Goal) Voraussetzung (Antezedenz, Rumpf, Body) • Wenn Aussagen A1 UND A2 UND ..An wahr, dann auch B wahr • Drei Arten von Klauseln • Regeln: Rechte und linke Seite vorhanden • Fakten (Axiome): Rechte Seite leer, d.h. ohne Voraussetzung erfüllt • Anfragen: Linke Seite leer Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 4 Logische Programmiersprachen Beispiel: Prolog (2) • Fakten: mutter (Eva, Tina). vater (Lars, Tina). mutter (Eva, Andreas). vater (Lars, Anreas). Lars Andreas Eva Tina • Regeln: elternteil (M, K) elternteil (V, K) vorfahr (X, Y) vorfahr (X, Y) :− mutter (M, K). :− vater (V, K). :− elternteil (X, Y). :− elternteil (X, Z), vorfahr (Z, Y). • Anfragen: ? vorfahr(Eva, Tina). ? vorfahr(Tina, W). Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 5 Logische Programmiersprachen Beispiel: Datalog als DB-Abfragesprache (1) Sei R Relation A B 1 2 3 4 • Relation R mit Hilfe von Prädikat modellieren: R(x,y) ist wahr, wenn (x,y) zu R gehört. R(1,2) ist wahr. R(3,4) ist wahr. R(5,7) ist falsch. • Regeln der Form Head ← Body können für Datenabfragen verwendet werden Weiteres Beispiel: Gegeben Relation Movie(title, year, length, inColor, studioName, producer) abgekürzt: Movie(t, y, l, c, s, p) Regel: LongMovie(t,y) ← Movie(t, y, l, c, s, p) AND l ≥ 100 Definiert Menge aller „langen“ Filme, die mindestens 100 Minuten lang sind. Anders formuliert: „LongMovie“ ist wahr, wenn es ein Tupel in „Movie“ gibt, so dass • irgendwelche Werte in den ersten zwei Komponenten existieren • eine dritte Komponente l existiert, die mindestens den Wert 100 hat • irgendwelche Werte in den Komponenten 4 bis 6 existieren Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 6 Logische Programmiersprachen Beispiel: Datalog als DB-Abfragesprache (2) Skizze in relationaler Algebra Komplexeres Beispiel: πtitle, year Finde Titel und Jahr aller Filme, die mindestens 100 Minuten lang sind und in die den Fox-Studios produziert wurden. ∩ Regeln: Selektiere Titel und Jahr Bilde Durchschnitt „Film-Tupel mit mindestens 100 Minuten “ W(t,y,l,c,s,p) ← Movie(t, y, l, c, s, p) AND l ≥ 100 „Film-Tupel mit Fox-Studios“ X(t,y,l,c,s,p) ← Movie(t, y, l, c, s, p) AND s = ‘Fox‘ „Film-Tupel mit mindestens 100 Minuten und Fox-Studios“ Y(t,y,l,c,s,p) ← W(t, y, l, c, s, p) AND X(t,y,l,c,s,p) „Selektiere Titel und Jahr aus Ergebnis Y“ Z(t,y) ← Y(t,y,l,c,s,p) Fakultät für Informatik Lehrstuhl für Programmiersysteme σlength ≥ 100 σstudioName=‘Fox‘ Wähle Tupel mit length ≥ 100 Wähle Tupel mit Studio Fox Movie Movie Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto Vgl. auch GarciaMolina et al., Database Systems 7 Parallelität in logischen Programmiersprachen Überblick • Parallelität wird im Wesentlichen dafür verwendet, um den Inferenzprozess zu beschleunigen • Zwei zentrale Ansätze • ODER-Parallelismus • UND-Parallelismus Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 8 Parallelität in logischen Programmiersprachen ODER-Parallelismus • ODER-Parallelismus führt Klauseln parallel aus • Beispiel: Regeln: a(x):- b(x). a(x):- c(x). „wenn b(x) wahr, dann a(x) wahr“ ODER „wenn c(x) wahr, dann a(x) wahr“ Anfrage: ? a(x) • ODER-Parallelismus führt parallel beide Klauseln a(x) aus Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 9 Parallelität in logischen Programmiersprachen UND-Parallelismus • UND-Parallelismus • teilt die Berechnung in mehrere Fäden auf, die parallel je eine Aussage evaluieren • Beispiel: Anfage: ?- a(x), b(x), c(x) • Erzeugt drei Fäden, die jeweils a(x), b(x), c(x) getrennt evaluieren Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 10 Parallelität in logischen Programmiersprachen Implizite Parallelisierung (1) • Parallelisierung mit UND- bzw. ODERParallelismus kann implizit durch den Interpreter erfolgen • Keine expliziten Annotationen durch Programmierer nötig • Mehrere Granularitätsstufen denkbar, z.B. • Feingranular: Jede Regel startet neuen Faden • Grobgranular: Ein Faden arbeitet auf eigenen Teilbaum (Baumstruktur entsteht bei Inferenz) • Beispiel-Implementierungen vgl. Skillikorn & Talia, Models and Languages for Parallel Computation, ACM Comp Surv. 30(2), 1998 Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 11 Parallelität in logischen Programmiersprachen Implizite Parallelisierung (2) • Typische Probleme: • Sprachen sehr abstrakt • Verhaltens- und Performanzvorhersage schwierig • Spekulativer Parallelismus Beim ODER-Parallelismus „spekuliert“ man darauf, dass die gesamte parallele Arbeit notwendig ist. Wenn man nur am ersten möglichen Ergebnis interessiert ist, kann man evtl. früher abbrechen. Das Programmiermodell sieht aber generell nicht vor, dass Fäden miteinander kommunizieren Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 12 Parallelität in logischen Programmiersprachen Explizite Parallelisierung (1) • Explizite Parallelisierung ist möglich • Entwickler muss entsprechende Konstrukte, wie z.B. Wächter-Bedingungen, einbauen B :- W1, W2, …, Wn | A1, A2, … , An Konsequenz (Kopf, Goal) Wächter Voraussetzung (Antezedenz, Rumpf) • Semantik: „B ist wahr, wenn Wächter wahr und Rumpf wahr“ • Wächter kann als ein Test angesehen werden. Regel nur wirksam, wenn Test erfolgreich • Wächter und Rumpf könnten parallel evaluiert werden (aber: Ergebnisse nur temporär, nur lokale Änderungen, die rückgängig gemacht werden können) • sobald Test fehlschlägt, werden Klausel und temporäre Ergebnisse verworfen, sonst „commit“ Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 13 Parallelität in logischen Programmiersprachen Explizite Parallelisierung (2) • Beispiel-Implementierungen, die expliziten Parallelismus verwenden • PARLOG (Gregory 1987) • Concurrent Prolog (Shapiro 1986) • Delta-Prolog (Pereira, Nasr 1984) Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 14 Parallelität in logischen Programmiersprachen • Verschiedene andere Erweiterungen wurden vorgeschlagen (vgl. Huntbach, Ringwood, Programming in Concurrent Logic Languages, IEEE Software, Nov. 1995) • Aber: Explizite Konstrukte für Parallelität weichen vom ursprünglichen Ziel logischer Sprachen ab, nur zu spezifizieren „was“ getan werden soll, nicht „wie“ Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 15 Funktionale Programmiersprachen Zur Erinnerung (1)… • Hauptprogramm ist eine Funktion • im mathematischen Sinne: Abbildung zwischen zwei Mengen (Werte aus Definitionsbereich werden auf Werte im Wertebereich abgebildet) • Funktion erhält Eingabedaten und bildet sie auf Ausgabedaten ab • Kann weitere Funktionen aufrufen • Auch hier steht deklarativer Ansatz im Vordergrund („was“, nicht „wie“) • Typische zentrale Datenstruktur: Liste Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 16 Funktionale Programmiersprachen Zur Erinnerung (2)… • Reine funktionale Sprachen (pure functional languages) • Variablen nur Platzhalter; sie repräsentieren keine Speicherstelle (d.h. „i=i+1“nicht möglich) • Keine Schleifen (sondern Rekursion) • Keine Seiteneffekte (z.B. innerhalb einer Funktion keine Aktualisierung globaler Variablen möglich) Æ Anwendung von Funktion auf bestimmtes Argument liefert immer das selbe Ergebnis. f(x) { return x+y;} Fakultät für Informatik Lehrstuhl für Programmiersysteme Gegenbeispiel: Sei y=1; f(1) liefert 2 // zwischenzeitlich y++; f(1) liefert 3 von f(1) liefert nichtFrank immer Dr. Victor Pankratius, Aufruf Prof. Walter F. Tichy, Dipl.-Inform. Otto 17 dasselbe Ergebnis 17 Funktionale Programmiersprachen Zur Erinnerung (3)… • Reine funktionale Sprachen (pure functional languages) ÆReferenzielle Transparenz: In einem Ausdruck A kann jeder beliebige Teilausdruck T durch einen Teilausdruck T‘ gleichen Wertes ersetzt werden, ohne dass sich der Wert von A verändert Beispiel: Referenzielle Transparenz ab+ab c + a b, a b + c, c + c, 2*c, 2*ab c=ab • Bei Sprachen mit Seiteneffekten ist keine referenzielle Transparenz vorhanden. Beispielsweise kann ab+ab ≠ 2*c sein, wenn zwischendurch a++ ausgeführt wird • Mit referenzieller Transparenz wird die Programmanalyse vereinfacht. Ein Ausdruck hängt nur von Teilausdrücken ab, nicht auch noch von der Reihenfolge der Auswertung oder von Seiteneffekten. Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 18 Funktionale Programmiersprachen Zur Erinnerung (4)… • Unreine funktionale Sprachen (impure functional languages) • Lockern einige der Einschränkungen auf • Erlauben z.B. Seiteneffekte (die z.B. durch Benutzerinteraktion, Art der Ein-/Ausgabe) Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 19 Funktionale Programmiersprachen Zur Erinnerung (5)… Beispiele in Scheme • (* 3 7) „*“ ist eine Funktion, die zwei Parameter benötigt; evaluiert zu 21 • (DEFINE (fac n) allgemein: (define (<name> <formale Parameter> <Rumpf>)) (IF (= n 0) 1 (* n (fac (- n 1))) )) • define (abs x) (cond ((> x 0) x) ((= x 0) 0) ((< x 0) (- x)))) Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 20 Funktionale Programmiersprachen Zur Erinnerung (6)… Beispiele in Scheme • (define x (cons 1 2)) (car x) liefert 1 (cdr x) liefert 2 • (list 1 2 3) ist äquivalent zu (cons 1(cons 2(cons 3 nil))) • (define (length items) (if (null? items) 0 (+ 1 (length (cdr items))))) (define l (list (1 2 3 4)) (length l) Länge einer leeren Liste ist 0 sonst 1+ Länge des cdr liefert 4 • (lambda (x) (+ x x)) evaluiert zu einer Funktion (ohne Namen) mit formalem Parameter x, die auf Folgeargumente angewendet werden kann (Parameter wird entsprechend gebunden) ((lambda (x) (+ x x)) 4) liefert 8 vgl. spätere Vorlesungen: delegates in C#, Vorschlag für „<>(…)“ Operator in C++0x Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 21 Funktionale Programmiersprachen Zur Erinnerung (7)… • Funktionen höherer Ordnung • Argument oder Ergebnis einer Funktion kann selbst eine Funktion sein • Beispiel: • Apply wendet Funktion an (apply + '(1 2)) Æ (+ 1 2) Gleicher Effekt, wie wenn man (+ 1 2) direkt aufgerufen hätte • Map wendet Funktion auf alle Elemente einer Liste an (map (abs (list 1 -2 3))) Æ (1 2 3) → kann parallel ausgeführt werden; für Datenparallelismus gut geeignet Æ SIMD → Verwendung beim MapReduce-Ansatz für verteilten und gemeinsamen Speicher Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 22 Parallelität in funktionalen Programmiersprachen • Evaluierung kann unterschiedlich erfolgen • Alle Argumente einer Funktion werden evaluiert, bevor die Funktion selbst evaluiert wird (z.B. Hope, OPAL) • Argumente werden nur evaluiert, wenn sie benötigt werden „lazy evaluation“ (z.B. Haskell, pH, Id) • Einfache Argumente (z.B. Integer) werden vor der Funktion ausgewertet, aber komplexe Argumente (z.B. Listen, rekursive Datenstrukturen) erst bei Bedarf Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 23 Parallelität in funktionalen Programmiersprachen Ansätze für Parallelismus (1) • Reine funktionale Sprachen haben vorteihafte Eigenschaften für Parallelisierung • Keine Seiteneffekte Æ Anwendung von Funktion auf bestimmtes Argument liefert immer dasselbe Ergebnis • Reihenfolge der Funktionsauswertung nicht festgelegt • Semantik über Abbildung von Ein- auf Ausgabedaten definiert Æ Jedes sequenzielle Programm wird für eine bestimmte Eingabe auch bei paralleler Ausführung dieselben Ergebnisse liefern und auch unter den gleichen Bedingungen terminieren. Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 24 Parallelität in funktionalen Programmiersprachen Ansätze für Parallelismus (2) • Implikationen • Parallele funktionale Programme könnten auch auf sequenziellen Rechnern entwickelt und getestet werden • Das Ergebnis ist unabhängig vom dynamischen Scheduling von Aufgaben • Verklemmungen sind nicht möglich, außer in Situationen in denen das sequenzielle Programm auch versagen würde (z.B. bei zyklischen Abhängigkeiten) Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 25 Parallelität in funktionalen Programmiersprachen Ansätze für Parallelismus (3) • Ansätze für Parallelismus • Implizite Partitionierung • Interpreter/Compiler entscheidet, welche Aufgaben parallel bearbeitet werden sollen • Explizite Partitionierung • Entwickler entscheidet, welche Ausdrücke parallel ausgeführt werden sollen • In beiden Fällen noch Auswahl zwischen • Statisch: Anzahl der zu erstellenden Aufgaben fix • Dynamisch: Aufgaben werden in Abhängigkeit von anderen Faktoren, wie z.B. aktuelle Auslastung, erstellt Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 26 Parallelität in funktionalen Programmiersprachen Ansätze für Parallelismus (5) • Impliziter Parallelismus – Beispiele für Realisierung • „Serial Combinators“ • Der Interpreter/Compiler fügt ohne Wissen des Entwicklers Pseudo-Funktionen für die Parallelisierung ein • Beispiel: fun n= if n<= 1 then 1 else 1+fun(n-1)+fun(n-2) Fakultät für Informatik Lehrstuhl für Programmiersysteme fun n= (demand n (spawn ((n1 (fun (n-1))) (n2 (fun (n-2)))) wait (n1 n2) (n1+n2+1)))) Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 27 Parallelität in funktionalen Programmiersprachen Ansätze für Parallelismus (6) • Expliziter Parallelismus • Annotations-Ansatz • Annotationen werden vom Entwickler explizit eingefügt • Grobgranular (z.B. Annotation ob Funktion überhaupt parallel ausgeführt werden soll) oder feingranular • Scheduling-Konstrukte (Prozess-Erstellung/Zerstörung, Ort der Ausführung, etc.) Beispiel: exp $on left($self) führe exp auf Prozessor aus, der sich „links“ vom aktuellen Prozessor befindet Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 28 Parallelität in funktionalen Programmiersprachen Skelette (1) • Algorithmische Skelette • Von Cole 1989 benannt • Idee: Erfasse häufig gebrauchte Verarbeitungsmuster, wie z.B. teile-und-herrsche, Fließbandverarbeitung oder „worker farm“, in Funktionen höherer Ordnung • Diese „Schablonen“ können dann vom Entwickler bei Bedarf instanziiert werden • Parallelität kann in einem Skelett „gekapselt“ werden • Wiederverwendung auf unterschiedlichen Architekturen: Nur plattformabhängiger Teil muss jeweils neu implementiert werden • Ähnlich zu Entwurfsmustern Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 29 Parallelität in funktionalen Programmiersprachen Skelette (2) • Algorithmische Skelette • Pseudocode-Beispiel für ein vereinfachtes Teile-und-herrsche-Skelett divCon divisible split join f L = if divisible then join (parmap f (split L)) else f L • Benutzer definiert Argumente: • • • • divisible (wahr/falsch) Liste L Funktionen split/join zum Aufteilen/Zusammenführen von L Funktion f, die auf „Basisfall“ angewendet werden soll • Parmap ist parallele „map“-Funktion, die f auf jedes Teilproblem angewendet Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 30 Parallelität in funktionalen Programmiersprachen Skelette (3) • Homomorphe Skelette • Basieren auf bestimmten Datentypen, z.B. Listen, Bäume, Graphen • Ersetze für folgende Beispiel: Liste Berechnungen f und g so: i-tes Element f f g f f g f f g f • Summe f = id, g=+ • Maximum f = id, g = binäres Maximum • Länge f = K1, g=+ f g Zeit g g g (K1 ist Funktion, die immer 1 zurückliefert) • Sort Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto f = id, g = merge 31 Parallelität in funktionalen Programmiersprachen Futures (1) • Futures • Konzept erstmals in Multilisp verwendet (Halstead, 1985) • Ein „Future“-Konstrukt ist ein Platzhalter für einen Wert • Am Anfang ist kein Wert bestimmt • Wenn initial das Konstrukt (future X) aufgerufen wird, liefert es dem Aufrufer einen Platzhalter und startet gleichzeitig einen Prozess, der X evaluiert Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 32 Parallelität in funktionalen Programmiersprachen Futures (2) • Futures (fortgesetzt) • Wenn der Wert bestimmt ist, wird der Platzhalter durch den ermittelten Wert ersetzt (Details gleich) • Eine Operation (z.B. Addition) wird suspendiert, falls sie den konkreten Wert benötigt, bevor er ermittelt ist Beispiel: (+ (future A) (future B)) „+“ wird suspendiert, bis die Werte vorhanden sind • Viele andere Operationen (z.B. Zuweisungen, Parameterübergabe, Rückgabe von Funktionen, Einfügen in Datenstrukturen) können mit dem Platzhalter arbeiten und benötigen den konkreten Wert nicht Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 33 Parallelität in funktionalen Programmiersprachen Futures (3) • Futures (fortgesetzt) • Futures erlauben eine Fortsetzung des Kontrollflusses über die Stelle hinaus, bei der auf einen Wert gewartet werden müsste • Synchronisation geschieht implizit und ist für Entwickler nicht sichtbar Æ Das Future-Konzept begegnet uns später auch bei Java und .NET Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 34 Parallelität in funktionalen Programmiersprachen Futures (4) • Einige Details zur internen Funktionsweise eines Future-Konstrukts • Future besteht aus (Wert W, Warteschlange S, booleschen Wert B, Sperre Sp) • Initial ist B=false, S: leer • Bei Zugriff auf Future führe folgendes atomar aus • Wenn B=true dann liefere W • Ansonsten suspendiere Aufrufer und füge ihn zu S hinzu (vermeidet „busy waiting“) • Wenn W ermittelt • Platzhalter wird zu Referenz auf W • Benachrichtige bzw. reaktiviere Aufrufer in Warteschlage S Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 35 Funktionale Programmiersprachen Stromverarbeitung (1) • Stromverarbeitung • Mit funktionalem Ansatz leicht umzusetzen • Beispielanwendungen: Datenströme (Datenstrom-Management- systeme), Signale, Multimedia, Fließbänder • Konzepte begegnen uns in ähnlicher Form bei „Stream“- Programmiersprachen im Multicore-Kontext • Zunächst einige motivierende Beispiele in Scheme (define (generator low high) (if (> low high) nil (cons low (generator (+ low 1) high)))) Aufruf: (generator 2 7) Ergebnis: (2 3 4 5 6 7) Fakultät für Informatik Lehrstuhl für Programmiersysteme generator Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto Wenn low<high, füge low zur Liste hinzu und rufe rekursiv generator mit [low+1, high] auf 36 Funktionale Programmiersprachen Stromverarbeitung (2) • Motivierende Beispiele (Fortsetzung) Filter predicate (define (filter predicate sequence) (cond ((null? sequence) nil) ((predicate (car sequence)) (cons (car sequence) (filter predicate (cdr sequence)))) (else (filter predicate (cdr sequence))))) Fallunterscheidung: - Wenn Sequenz leer, gib nil zurück - Prädikat für erstes Element wahr, dann nimm Element in Liste auf und wende Filter mit Prädikat auf Rest der Liste an - Prädikat nicht zutreffend: Wende Filter auf Rest der Liste an Aufruf: (filter odd? (generator 1 5)) Ergebnis: (1 3 5) Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 37 Funktionale Programmiersprachen Stromverarbeitung (3) • Motivierende Beispiele (Fortsetzung) Accumulate op initial (define (accumulate op initial sequence) (if (null? sequence) initial (op (car sequence) (accumulate op initial (cdr sequence))))) Wenn Sequenz leer, gib initialen Wert zurück, ansonsten wende Operator auf erstes Element und dem akkumulierten Rest der Liste an Beispiel-Aufrufe Vgl. auch Reduktion (accumulate + 0 (generator 1 5)) Æ 15 (accumulate * 1 (generator 1 5)) Æ 120 (accumulate cons nil (generator 1 5)) Æ (1 2 3 4 5) Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 38 Funktionale Programmiersprachen Stromverarbeitung (4) • Motivierende Beispiele (Fortsetzung) • Kombiniere Operatoren (define (sum-odd-quares n) (accumulate + 0 (map square (filter odd? (generator 0 n))))) generator filter odd? square accumulate (define (even-fibs n) (accumulate cons nil (filter even? (map fib (generator 0 n))))) generator Fakultät für Informatik Lehrstuhl für Programmiersysteme map fib filter even accumulate Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 39 Funktionale Programmiersprachen Stromverarbeitung (5) • Motivierende Beispiele (Fortsetzung) • Kombiniere Operatoren Liste von Listen (define (salary-of-highest-paid-programmer records) (accumulate max 0 (map salary (filter programmer? records)))) „Selektor“: Liefert Betrag des Gehaltes aus Datensatz Fakultät für Informatik Lehrstuhl für Programmiersysteme Überprüft, ob bestimmter Datensatz der eines Programmierers ist Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 40 Funktionale Programmiersprachen Stromverarbeitung (6) • Ströme • Probleme mit bisherigem Ansatz: • Strom ist als Liste implementiert • Datenstruktur endlich • Hoher Speicherverbrauch / Rechenzeit bei langen Strömen (define (sum-primes a b) (accumulate + 0 (filter prime? (generator a b)))) Generiert zunächst das gesamte Intervall Fakultät für Informatik Lehrstuhl für Programmiersysteme Erst wenn Generator fertig ist, wird das Prädikat angewendet; es wird eine neue Liste mit Ergebnissen generiert, die an accumulate übergeben wird. Ein solch großes Zwischenergebnis Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto wäre bei inkrementeller 41 Enumeration und Weitergabe nicht notwendig Funktionale Programmiersprachen Stromverarbeitung (7) • Ströme • In Realität: Datenstrom kann sich mit der Zeit ändern • Stromlämge kann potenziell unendlich sein • Neue Datenstruktur “Datenstrom” • Idee: Konstruiere einen Datenstrom nur partiell und übergebe zunächst nur denjenigen Teil, der gerade benötigt wird, an einen Konsumenten • Verzögerte Auswertung (“lazy evaluation”) • Wenn Konsument auf einen Teil zugreifen will, der noch nicht existiert, dann werden automatisch gerade so viele neue Elemente produziert, wie vom Konsumenten benötigt. Æ Für Konsumenten: Illusion, dass kompletter Strom existiert • Programm wird so geschrieben, als ob komplette Sequenz vollständig vorhanden wäre Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 42 Funktionale Programmiersprachen Stromverarbeitung (8) • Vergleich • Liste 1 2 3 • Strom 1 Fakultät für Informatik Lehrstuhl für Programmiersysteme 2 3 4 … „Versprechen“, das nächste Element zu liefern, sobald es gebraucht wird Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 43 Funktionale Programmiersprachen Stromverarbeitung (9) • Operationen auf Datenstrom • Analog zu Operatoren auf Listen z.B. cons-stream, stream-null?, the-empty-stream, stream-car, stream-cdr, stream-map, stream-generate • Jedoch geringfügig modifiziert, damit verzögerte Verarbeitung funktioniert Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 44 Funktionale Programmiersprachen Stromverarbeitung (10) • Die verzögerte Auswertung • kann auch mit expliziten Konstrukten kontrolliert werden • (delay exp) evaluiert Ausdruck exp nicht sofort, sondern “verspricht” ihn irgendwann in der Zukunft zu evaluieren • force bekommt einen mit delay verzögerten Ausdruck als Argument und evaluiert ihn (force “zwingt” das Delay-Konstrukt, das “Versprechen” einzulösen). (cons-stream <a> <b>) (cons <a> (delay <b>)) ist äquivalent zu Beispiel zur Konstruktion eines Stroms mit Hilfe von Paaren. Im cdr werden nicht von Anfang an alle übrigen Werte abgelegt, sondern nur Versprechen zur Evaluation bei Bedarf (define (stream-car stream) (car stream)) stream-cdr selektiert cdr des Paares und erzwingt seine (define (stream-cdr stream) (force (cdr stream))) Evaluation, um Rest des Stroms zu bekommen Fakultät für Informatik 45 Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto Lehrstuhl für Programmiersysteme Funktionale Programmiersprachen Stromverarbeitung (11) • Weitere Beispiele Datenstrom mit unendlich vielen Elementen (define (integers-starting-from n) (cons-stream n (integers-starting-from (+ n 1)))) Addition von Datenströmen (define (add-streams s1 s2) (stream-map + s1 s2)) Mehr dazu: Vgl. auch Abelson et al., Structure and Interpretation of Computer Programs MIT Press, 1984 Volltext online: http://mitpress.mit.edu/sicp/full-text/book/book.html Fakultät für Informatik Lehrstuhl für Programmiersysteme Dr. Victor Pankratius, Prof. Walter F. Tichy, Dipl.-Inform. Frank Otto 46