800 likes | 932 Views
Linda und JavaSpaces. Linda. Motivation / Einführung Parallele Kommunikationsstrukturen Beschränkungen Probleme. Linda. Motivation / Einführung Parallele Kommunikationsmuster Beschränkungen Probleme. Message Passing. Prozess. Prozess. send. send. send. rcv. rcv. Prozess. rcv.
E N D
Linda • Motivation / Einführung • Parallele Kommunikationsstrukturen • Beschränkungen Probleme
Linda • Motivation / Einführung • Parallele Kommunikationsmuster • Beschränkungen Probleme
Message Passing Prozess Prozess send send send rcv rcv Prozess rcv send send rcv Prozess Prozess rcv rcv rcv send send
Message Passing ? Prozess Prozess send send send rcv Prozess rcv send send rcv Prozess Prozess rcv rcv rcv send send
Linda • wurde in den 80er Jahren von Prof. David Gelernter an der Yale University entwickelt. • stellt ein alternatives Paradigma der parallelen Programmierung dar. • beruht auf dem Konzept des tuple-space …
tuple-space • zentraler Datenspeicher zur Kommunikation • ähnlich schwarzem Brett • Prozesse können Tupel erzeugen, Tupel lesen und Tupel entfernen • jeder Prozess hat vollen Zugriff auf den tuple-space • sämtliche Kommunikation läuft durch erstellen und lesen der Tupel ab • es gibt keine weiteren Kommunikationsmechanismen wie z.B. Nachrichten
Linda • Satz sprachunabhängiger Kommunikationsoperationen zur Interaktion mit dem tuple-space. • 4 Grundoperationen: • in • out • rd • eval
tuple-space tuple-space - Operationen • out - Erzeugen eines Tupels out Prozess
tuple-space tuple-space - Operationen • rd - Lesen eines Tupels rd Prozess
tuple-space tuple-space - Operationen • in - konsumierendes Lesen eines Tupels in Prozess
tuple-space Kommunikationsschema Prozess Prozess out out Prozess in Prozess Prozess rd rd
Hello World Prozess 1: out("Hello World!"); Prozess 2: in(? msg); printf("%s", msg);
tuple-space Hello World Prozess 1: out("Hello World!"); Prozess 2: in(? msg); printf("%s", msg);
tuple-space Hello World Prozess 1: out("Hello World!"); Prozess 2: in(? msg); printf("%s", msg);
in • Gesucht wird ein Tupel, dessen • erste n Komponenten mit value1, …, valuen übereinstimmen • letzte n Komponenten mit den Typen von var1, … varn übereinstimmen • Die Werte der letzten n Einträge werden in den Variablen var1, …, varn abgelegt. • Blockiert bis gesuchtes Tupel vorhanden in(value1,…, valuen, ? var1, …, ? varn);
rdp, inp Prädikatoperationen: • rdp – inp: • versuchen spezifizierten Wert zu lesen, liefern 1 im Erfolgsfall, 0 sonst. • nicht blockierend • variierende Ausführungsgeschwindigkeiten der beteiligten Systeme Nichtdeterminismus
eval eval – Erzeugung eines neuen Prozesses: • verhält sich wie out, legt jedoch einen neuen Prozess an um den Wert des einzufügenden Tupels zu berechnen. out(x, f(x)); • der Wert y von f(x) wird bestimmt • das Tupel (x, y) wird dem tuple-space hinzugefügt • die Anweisung kehrt zurück eval(x, f(x)); • es wird ein neuer Prozess p erzeugt • die Anweisung kehrt zurück • p berechnet y und fügt das Tupel (x, y) dem tuple-space hinzu
Linda • Motivation / Einführung • Parallele Kommunikationsmuster • Beschränkungen Probleme
TS Master-Worker Schema Worker: int number; while (!done) { in("task", ? number); if (is_prime(number)) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 2; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker Worker
TS Master-Worker Schema Worker: int number; while (!done) { in("task", ? number); if (is_prime(number)) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 2; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker Worker
TS Master-Worker Schema Worker: int number; while (!done) { in("task", ? number); if (is_prime(number)) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 2; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker Worker
TS Master-Worker Schema Worker: int number; while (!done) { in("task", ? number); if (is_prime(number)) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 2; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker Worker
TS Master-Worker Schema Worker: int number; while (!done) { in("task", ? number); if (is_prime(number)) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 2; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker Worker
Datenstrukturen • Pseudo-Datenstrukturen durch Nutzung von Bennenungsschemata: Matrix: Vektor: out(1, firstelt) out(2, secondelt) out(n, nthelt) out(1, 1, elem11) … out(1, n, elem1n) out(2, 1, elem21) … out(2, n, elem2n) out(n, 1, elemn1) … out(1, n, elemnn) … … …
Vektorberechnung 1:1 Prozess Datenelement Datenelement = Tupel 1 eval-Anweisung pro Datenelement int lmain() { for (int i = 0; i < VEC_SIZE; i++) { eval( i, combine(a[i], b[i]) ); } return 0; }
Message Passing Emulation von Kanälen im tuple-space: • Queue-Struktur - FIFO • Nummerierung der Nachrichten • spezielle Tupel zur Verwaltung des aktuellen Zählerstandes von Anfang und Ende der Queue void send_msg(int msg) { int tail_index; in("my_channel", "tail", ? tail_index); out("my_channel", tail_index + 1, msg); out("my_channel", "tail", tail_index + 1); }
Message Passing int rcv_msg() { int head_index; in("my_channel", "head", ? head_index); in("my_channel", head_index, ? msg); out("my_channel", "head", head_index + 1); } void send_msg(int msg) { int tail_index; in("my_channel", "tail", ? tail_index); out("my_channel", tail_index + 1, msg); out("my_channel", "tail", tail_index + 1); }
Entwurfstechnik • Erstelle paralleles Programm. Nutze Kommunikationstechnik (message passing, eval-Tupel, master-worker…), die sich intuitiv anbietet. • Transformiere Programm ggf. (Performance) hin zu effizienterem Muster. Vorteil: Alle Programmtransformationen können innerhalb von Linda realisiert werden.
Linda • Motivation / Einführung • Parallele Kommunikationsmuster • Beschränkungen Probleme
Endloses Blockieren rd, in blockieren u.U. endlos: • es ist nicht möglich einen Timeout zu spezifizieren • testet man mittels der Prädikatoperationen rdp und inp kommt es zum busy-waiting und man läuft Gefahr, das gewünschte Tupel zu verpassen while ( !inp(t) ) {} while ( !inp(t) ) { sleep(some_time); } unnötig hohe Systembelastung erhöhte Gefahr des Verpassens
TS Black-Box Effekt • i.A. sehr schwierig Überblick über den Inhalt des tuple-space zu gewinnen • Wie können mehrere (alle) Tupel zu einer Suchanfrage gefunden werden? ?
rd("search", ? value1); rd("search", ? value2); ? TS Black-Box Effekt ?
rd("search", ? value1); rd("search", ? value2); nicht korrekt! aufgrund des Nichtdeterminismus kann zweimal das gleiche Tupel ausgewertet werden TS Black-Box Effekt ?
Black-Box Effekt Lösung: • alle relevanten Tupel konsumieren • Tupel zurückschreiben void read_all() { int counter = 0, value; int tuples[SIZE]; while ( inp("entry", ? value) ) { tuples[counter] = value; counter++; } for (int i = 0; i < counter; i++) { out("entry", tuples[i]); } }
Black-Box Effekt Lösung: • alle relevanten Tupel konsumieren • Tupel zurückschreiben void read_all() { int counter = 0, value; int tuples[SIZE]; while ( inp("entry", ? value) ) { tuples[counter] = value; counter++; } for (int i = 0; i < counter; i++) { out("entry", tuples[i]); } }
Black-Box Effekt Lösung: • alle relevanten Tupel konsumieren • Tupel zurückschreiben void read_all() { int counter = 0, value; int tuples[SIZE]; while ( inp("entry", ? value) ) { tuples[counter] = value; counter++; } for (int i = 0; i < counter; i++) { out("entry", tuples[i]); } }
Black-Box Effekt Problem: Was, wenn der tuple-space während des Auslesens modifiziert wird?
Black-Box Effekt Lösung: • wechselseitiger Ausschluss bei Schreibzugriffen • Nachbildung von Semaphorfunktionalität in("write_mutex"); … out("write_mutex"); P(write_mutex); … V(write_mutex);
Black-Box Effekt Lösung: void read_all() { in("write_mutex"); int counter = 0, value; int tuples[SIZE]; while ( inp("entry", ? value) ) { tuples[counter] = value; counter++; } for (int i = 0; i < counter; i++) { out("entry", tuples[i]); } out("write_mutex"); }
TS Aufstauung • nicht benötigte Tupel sammeln sich im TS an • Black-Box Effekt: • schwer Übersicht zu behalten • garbage collection mühsam
Teilausfall Verteilte Umgebung (LAN, Internet, etc.): • mit dem tuple-space verbundene Systeme können jederzeit ausfallen • aufgrund der Struktur des tuple-space Modells hat ein Prozess keine Kenntnis über andere aktive Prozesse • ein Ausfall wird nicht bemerkt
TS Teilausfall Worker: int number; while (!done) { in("task", ? number); if (is_prime(number)) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 0; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker Worker
TS Teilausfall Worker: int number; while (!done) { in("task", ? number); if (is_prime(number)) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 0; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker Worker
TS Teilausfall Worker: int number; while (!done) { in("task", ? number); if (is_prime(number)) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 0; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker
TS Master-Worker Schema Worker: int number; while (!done) { in("task", ? number); if (is_prime(number)) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 0; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker
TS Master-Worker Schema Worker: int number; while (!done) { in("task", ? number); if (is_prime(number) { out("result", number, TRUE); } else { out("result", number, FALSE); } Master: for (int i = 0; i < MAX; i++) { out("task", i); } bool result; int number; for (int i = 0; i < MAX; i++) { in("result", ? number, ? result); } Worker Master Worker
Zusammenfassung • Linda bietet ein klares Anweisungssystem zur Entwicklung paralleler Programme. • Eine Vielzahl an Kommunikationsmustern ist realisierbar. • Die Prozessgranularität ist kontrollierbar. • Prozesse sind schwach gekoppelt. • Einsatz in verteilten Umgebungen Einige Probleme im praktischen Einsatz.
JavaSpaces • Einführung • Adressierte Probleme • Weitere Möglichkeiten
JavaSpaces • Einführung • Adressierte Probleme • Weitere Möglichkeiten