Bulk Synchronous Parallel Computing

Westfälische Wilhelms-Universität Münster Ausarbeitung Bulk Synchronous Parallel Computing im Rahmen des Seminars Parallele Programmierung Michael ...
Author: Fanny Michel
2 downloads 2 Views 60KB Size
Westfälische Wilhelms-Universität Münster

Ausarbeitung

Bulk Synchronous Parallel Computing im Rahmen des Seminars Parallele Programmierung

Michael Poldner

Themensteller: Prof. Dr. Herbert Kuchen Betreuer: Roger Müller Institut für Wirtschaftsinformatik Praktische Informatik in der Wirtschaft

Inhaltsverzeichnis 1

Einleitung ...................................................................................................................1

2

Berechnungsmodelle ..................................................................................................1

3

Parallel Random Access Machine (PRAM)...............................................................2

4

Bulk Synchronous Parallel Modell ............................................................................5 4.1

Modellbeschreibung..........................................................................................5

4.2

BSPlib-Programmierung .................................................................................10

4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6

Starten und Beenden von SPMD-Code.......................................................11 Simulation dynamischer Prozesse...............................................................12 Stoppen der Programmausführung..............................................................13 Lokale Abfragefunktionen ..........................................................................13 Superschritte................................................................................................14 Kommunikation...........................................................................................14

4.3

Diskussion des BSP-Modells und seiner Varianten........................................16

4.4

BSP in der Praxis ............................................................................................17

5

Fazit..........................................................................................................................18

6

Literaturverzeichnis .................................................................................................19

II

1 Einleitung Seit über einem halben Jahrhundert ist die von-Neumann-Maschine die Grundlage fast aller digitalen sequentiellen Computer. Dieses über die Jahre stabile Modell förderte in hohem Maße den Ausbau der Soft- und Hardwareindustrie, weil es die Entkopplung von Hardware- und Softwareentwicklung ermöglichte. Die Geschichte der Parallelrechner war jedoch weit weniger von Erfolg gekrönt, da aufgrund des rasanten Fortschritts in der VLSI-Technologie in den achtziger Jahren die Betrachtung der Hardware die treibende Kraft für den Entwurf paralleler Systeme war. Hieraus resultierte eine Vielzahl unterschiedlicher Architekturen. Das brachte das Problem mit sich, dass oftmals die Software speziell an diese Architekturen angepasst werden musste und bestehende Software nicht oder nur schwer auf andere Rechnersysteme übertragen werden konnte. Aufgrund dieser Tatsache waren Parallelrechner vergleichsweise teuer und schnell veraltet, und sie konnten sich auf dem Markt nur schwer durchsetzen. Erst Anfang der neunziger Jahre suchte man den Erfolg in einem einheitlichen und allgemein anerkannten Modell, vergleichbar mit dem von-Neumann-Modell im sequentiellen Bereich, welches sowohl eine skalierbare parallele Performance, als auch eine architekturunabhängige Softwareentwicklung erlauben sollte. In dieser Arbeit werden zwei solcher Modelle vorgestellt, die Parallel Random Access Machine (PRAM) und das Bulk Synchronous Parallel (BSP)-Modell. Hauptaugenmerk wird auf das BSP-Modell gerichtet. Beide Modelle können im Rahmen dieser Arbeit nicht detailliert behandelt werden, dennoch soll der Leser einen Einblick in die Funktionsweise dieser Modelle, deren Stärken und Schwächen, sowie deren Programmierung gewinnen. Abgerundet wird die Arbeit durch einen kurzen Überblick über BSPModellvarianten und ein Beispiel für den praktischen Einsatz des Bulk Synchronous Parallel Computing.

2 Berechnungsmodelle Berechnungsmodelle dienen zur Analyse von Algorithmen. Algorithmen werden hinsichtlich eines Bewertungskriteriums (z.B. Laufzeit und Speicherplatzverbrauch in Abhängigkeit von der Eingabegröße) und unabhängig von einer Programmiersprache und eines bestimmten Rechners bewertet. Dazu ist es notwendig, ein Modell eines Rechners 1

zugrunde zu legen, anhand dessen eine solche Bewertung erfolgen kann. Ein Berechnungsmodell abstrahiert von konkreten Rechnerdetails, gibt aber dennoch wichtige Merkmale einer Klasse von Rechnern an, welche signifikanten Einfluss auf die Laufzeit von Algorithmen haben. Dazu erfassen Berechnungsmodelle die Basisoperationen, welche vom Rechnersystem ausgeführt werden können, und beschreiben, wann die damit zusammenhängenden Aktionen stattfinden, wie Daten gespeichert werden und wie auf diese Daten zugegriffen werden kann (vgl. [RR98, S.347f]). Ein Berechnungsmodell stellt somit ein einheitliches Rechnermodell zur Verfügung, auf dem ein einfaches und komfortables Programmiermodell möglich wird [Sch98]. Ein häufig benutztes Berechnungsmodell für sequentielle Rechner ist das Random Access Machine (RAM)-Modell. Eine Random Access Machine ist im wesentlichen ein Random Access Memory von unbeschränkter Kapazität. Eine Speicherzelle kann ein Wort beliebiger Größe speichern und ein Schreib- oder Lesezugriff kann in konstanter Zeit geschehen. Weiterhin verfügt eine RAM über eine Recheneinheit, welche arithmetische Operationen (+, -, *, /) in konstanter Zeit und unabhängig von der Größe der Operanden berechnen kann. Im folgenden werden zwei parallele Berechnungsmodelle, das PRAM-Modell und das BSP-Modell vorgestellt.

3 Parallel Random Access Machine (PRAM) Das PRAM-Modell dient zur Analyse von parallelen Algorithmen. Das Rechnermodell sieht eine unbeschränkte Anzahl von Prozessoren vor, welche von einer globalen Uhr gesteuert synchron zueinander das gleiche Programm ausführen. Jeder Prozessor kann auf einen eigenen lokalen Speicher zugreifen.1 Die Kommunikation zwischen den einzelnen Prozessoren, sowie deren Synchronisation, erfolgt über einen gemeinsamen Speicher unbeschränkter Größe (vgl. Abb. 1a). Folgendes Beispiel zeigt eine einfache Synchronisation von zwei Prozessoren über eine globale Variable:

1

In der Literatur finden sich unterschiedliche Darstellungen einer PRAM-Maschine. Im Gegensatz zu [RR98] geht McColl in [ST95] davon aus, dass die Prozessoren bis auf eine feste Anzahl von Registern über keinen lokalen Speicher verfügen. In dieser Arbeit wird dem Ansatz in [RR98, S.348] gefolgt.

2

Prozessor 0:

Prozessor 1:

var = 0;

...

...

while (var == 0) {...}

var = 1;

...

Der Zugriff auf eine beliebige lokale oder globale Speicherzelle kann in konstanter Zeit geschehen. Greifen mehrere Prozessoren gleichzeitig auf eine Speicherzelle zu, können Konflikte entstehen. Insofern sind Methoden anzugeben, welche Speicherzugriffskonflikte vermeiden. Anhand der Art der Konfliktbehandlung lassen sich vier PRAMVarianten unterscheiden. Die Exclusive Read Exclusive Write (EREW)-PRAM verbietet den gleichzeitigen Zugriff auf dieselbe Speicherzelle, während die Concurrent Read Concurrent Write (CRCW)-PRAM einen gleichzeitigen Zugriff erlaubt. Eine Concurrent Read Exclusive Write (CREW)-PRAM erlaubt simultanes Lesen und verbietet das gleichzeitige Schreiben. Umgekehrt verbietet eine Exclusive Read Concurrent Write (ERCW)-PRAM simultane Lesezugriffe, erlaubt aber das simultane Schreiben. Bei gleichzeitigen Schreibzugriffen (CW) sind mehrere Varianten denkbar. (1) ein gemeinsames Schreiben ist nur dann erlaubt, wenn alle Prozessoren den gleichen Wert in die Speicherzelle schreiben (Common-CW); (2) bei gemeinsamen Schreiben gewinnt ein beliebiger Prozessor nach einem nichtdeterministischen Wahlverfahren (ArbitraryCW); (3) jedem Prozessor wird eine Priorität zugeordnet und derjenige Prozessor mit der höchsten (niedrigsten) Priorität gewinnt (Priority-CW); (4) die Summe der Werte der einzelnen Prozessoren wird in die Speicherzelle geschrieben; (5) nur der kleinste (größte) zu schreibende Wert wird in die Speicherzelle geschrieben (vgl. [ST95, S.340], [RR98, S.348f.], [Sch98, S.8]). Das CREW-PRAM-Modell kommt der Realität am nächsten. Die Kosten eines Algorithmus werden mit der Anzahl der benötigten PRAM-Schritte angegeben. Jeder PRAM-Schritt besteht aus folgenden drei Teilschritten (bzw. einer beliebigen Untermenge), dem Lesen von Daten aus dem gemeinsamen Speicher, einer einfachen binären Operation und dem Zurückschreiben eines Werts in den gemeinsamen Speicher. Nach jedem Schritt erfolgt eine Synchronisation aller Prozessoren (lockstep-Ausführung), bevor der nächste Schritt ausgeführt wird. PRAM-Modelle idealisieren Parallelrechner, indem die Synchronisation keine zusätzliche Kosten verursacht.

3

PRAM-Algorithmen bestehen aus zwei Phasen. Zunächst werden alle n benötigten Prozessoren aktiviert (Notation: spawn(P1, ... Pn)), anschließend erfolgt die Durchführung der parallelen Berechnung (Notation: for all (Pi1, ... , Piq) { ... }; Annahme: implizierte Synchronisation (Barriere) am Ende). Identifiziert wird ein Prozessor durch eine Nummer bzw. einen Index, der lokal zur Verfügung steht und auf den im Programm eines Prozessors zugegriffen werden kann. Zur Veranschaulichung dient folgender Algorithmus zur Berechnung der Summe aller Werte in einem Feld der Größe n. Die Laufzeit liegt in Θ(log n).

global int A[n]; global int j;

// 1. Phase: Aktivieren der benötigten Prozessoren spawn (P0, P1, … , Pn/2-1);

// 2. Phase: Ausführen der parallelen Berechnungen for all (Pi where 0 ≤ i ≤ n/2-1 ) { for (j = 0; j < log n; j++) { if (i % 2j == 0 && 2i + 2j < n) { A[2i] = A[2i] + A[2i + 2j] } } }

Das PRAM-Modell besticht durch seine Einfachheit und wird oft für die theoretische Analyse paralleler Algorithmen herangezogen, da die Kosten für eine Synchronisation nicht beachtet und die Kosten für einen Speicherzugriff als uniform angesehen werden. Tatsächlich ist dieses Modell aber für eine realistische Abschätzung der Laufzeit von parallelen Algorithmen ungeeignet. Das abstrakte Modell der PRAM ist nach dem heutigen Stand der Technik nicht realisierbar, da es nicht möglich ist, Speicherelemente zu bauen, die beliebig viele simultane Zugriffe in konstanter Zeit erlauben. 4

S1

S2

...

gemeinsamer

Verbindungs-

Speicher S

netzwerk

P1

P2

L1

L2

...

Pn

P1

P2

Ln

L1

L2

(a) PRAM

...

Sm

Pn Ln

(b) PRAM mit Verbindungsnetzwerk

Pi: Prozessoren ; Li: lokale Speicher ; Si: globale Speichermodule Abb.1: Veranschaulichung des PRAM-Modells

Man behilft sich, indem man den globalen Speicher in mehrere Speichermodule aufteilt, welche über ein Verbindungsnetzwerk mit den Prozessoren verbunden sind (vgl. Abb.1b). Im Gegensatz zum abstrakten Modell ist die Anzahl der Zugriffsmöglichkeiten auf ein Speichermodul begrenzt und es treten Verzögerungen auf, wenn auf entfernte Speichermodule zugegriffen wird. Zudem kann der Zugriff auf eine lokale Speicherzelle deutlich schneller erfolgen als ein Zugriff auf den globalen Speicher. Insofern kann von einer uniformen Zugriffszeit auf den Speicher nicht die Rede sein. Auch berücksichtigt das Modell keine Kollisionen beim Zugriff auf den globalen Speicher und die für die meisten Rechner vorhandenen Speicherhierarchien werden ebenfalls nicht berücksichtigt. Ein weiterer Kritikpunkt ist, dass das PRAM-Modell durch seine vereinfachten Annahmen die Lokalität eines Algorithmus unberücksichtigt lässt. Somit kann ein Algorithmus mit hoher Lokalität gegenüber einem Algorithmus mit niedriger Lokalität nicht positiv bewertet werden. Zudem ist auch ist die fehlende Betrachtung des Synchronisationsmechanismus und dem damit verbundenen hohen Kommunikationsbedarf als Nachteil zu sehen.

4 Bulk Synchronous Parallel Modell 4.1 Modellbeschreibung Das Bulk Synchronous Parallel (BSP)-Modell wurde 1990 von Leslie Valiant als Brücke zwischen Software- und Hardwarelösungen vorgestellt [Va90]. Das Modell be5

schreibt einen abstrakten Rechner mit verteiltem Speicher. Jeder Prozessor kann über einen eigenen lokalen Speicher verfügen. Die Prozessoren sind über ein Verbindungsnetzwerk untereinander verbunden, über welches im Punkt-zu-Punkt-Transfer Nachrichten zur Kommunikation verschickt werden. Weiterhin zeichnet sich ein BSPRechner durch einen Mechanismus zur Barriere-Synchronisation aller, oder einer Teilmenge der Prozessoren aus. Die folgende Abbildung veranschaulicht das Modell.

Verbindungsnetzwerk P1

P2

L1

L2

...

Pn Ln

Pi: Prozessoren; Li: lokale Speicher Abb. 2: BSP-Computer

Geht man davon aus, dass die Ausführung einer einzelnen lokalen Operation, d.h. einer Basisoperation, welche auf lokal gehaltene Daten ausgeführt wird, in einem Berechnungsschritt erfolgen kann, so lässt sich die Performance eines BSP-Rechners über folgende Parameter näher spezifizieren:



p: Die Anzahl der (virtuellen) Prozessoren



s: Die Prozessorgeschwindigkeit, angegeben durch die Anzahl der Berechnungsschritte, die der Prozessor pro Sekunde durchführen kann



l: Synchronisationslatenz (die Anzahl der Schritte, die eine Barrieresynchronisation benötigt)



g: (Die Summe der lokalen Operationen, welche durch alle Prozessoren in einer Sekunde ausgeführt werden) / (Die Summe der Wörter, welche in einer Sekunde über das Netzwerk verschickt werden)

Die Synchronisationslatenz l wird in hohem Maße von der Netzwerklatenz und dem Durchmesser des Verbindungsnetzwerks beeinflusst. Durch die Hardware ist somit eine bestimmte Untergrenze für diesen Parameter festgelegt. Das BSP-Modell erlaubt es, die 6

Zeitspanne zwischen zwei Synchronisationsoperationen dynamisch zur Laufzeit zu variieren. Der Parameter g bezieht sich auf die Häufigkeit mit welcher nicht lokale Speicherzugriffe realisiert werden können. Er stellt die Bandbreite des Netzwerks dar, die angibt, wie viele Operationen in der Zeit ausgeführt werden können, die das Verschicken eines Wortes benötigt. Der Wert g hängt sowohl von der Bisektionsbandbreite des Verbindungsnetzwerkes (Bandbreite zwischen den Teilnetzen, die entstehen, wenn man das Verbindungsnetz in zwei Netze mit gleicher Anzahl von Knoten aufteilt), als auch vom verwendeten Kommunikationsprotokoll und der Implementierung der verwendeten Kommunikationsbibliothek ab [RR98]. Da die Prozessorgeschwindigkeit s im Prinzip ein Normalisierungsfaktor ist, bleiben drei unabhängige Parameter: p, l und g, welche den sogenannten BSP-Raum aufspannen. Jede parallele Maschine, welche dem BSPModell entspricht, kann in einem Punkt im BSP-Raum über das Parameter-Tripel (p ,l, g) lokalisiert werden [Gu99].

p

g

l

Abb.3: BSP-Raum

Eine Berechnung erfolgt in einer Folge von Superschritten. Ein Superschritt besteht jeweils aus drei Phasen, einer Berechnungsphase, einer Kommunikationsphase und einer Synchronisationsphase (vgl. Abbildung 4). Während eines Superschritts führt jeder Prozessor eine bestimmte Menge von Programmen bzw. Prozessen aus. Die Ausführung von Operationen erfolgt ausschließlich in der Berechnungsphase. Innerhalb dieser Zeit kann jeder Prozess mehrere Berechnungsschritte durchführen, wobei die ausgeführten Operationen alle ausschließlich auf im Speicher des Prozessors lokal gehaltene Daten arbeiten, welche zu Beginn des Superschritts verfügbar waren. Ein Datenaustausch zwischen den einzelnen Prozessoren

7

ist in dieser Phase nicht erlaubt.2 Die Dauer L der Berechnungsphase ergibt sich aus der Ausführungszeit des Prozessors, welcher die längste lokale Berechnung durchführt. Nicht lokale Schreib- und Leseanfragen werden innerhalb der Kommunikationsphase über das Senden und Empfangen von Nachrichten realisiert. Die Kommunikation zwischen den Prozessoren lässt sich durch eine h-Relation beschreiben. Jeder Prozessor darf in dieser Phase maximal h Nachrichten versenden und maximal h Nachrichten empfangen. Unter der Annahme, dass eine Nachricht aus m Wörtern besteht, lässt sich die Kommunikation in m * g * h Schritten realisieren. Im BSP-Modell werden zwei Kommunikationsmodi vorgeschlagen, Direct Remote Memory Access (DRMA) und Bulk Synchronous Message Passing (BSMP), welche durch einige BSP-Bibliotheken, z.B. die BSPlib oder JBSP [GBW01], unterstützt werden. DRMA zeichnet sich dadurch aus, dass jeder Prozess auf den lokalen Speicher eines anderen Prozesses zugreifen kann, ohne dass eine aktive Teilnahme des Zielprozesses notwendig ist. Es werden zu diesem Zweck vier Operationen bereitgestellt: bsp_push_reg, bsp_pop_reg, bsp_put und bsp_get. Damit auf lokal gespeicherte Daten global zugegriffen werden kann, ist ein Registrierungsmechanismus notwendig. Die beiden Operationen bsp_push_reg und bsp_pop_reg erklären eine lokale Datenstruktur für den DRMA-Zugriff als global verfügbar bzw. nicht verfügbar. Derartige Registrierungen werden erst im nächsten Superschritt wirksam. Über die beiden Operationen bsp_get und bsp_put kann lesend bzw. schreibend auf registrierte Datenstrukturen und Variablen zugegriffen werden. Auch der Effekt des Datenaustauschs ist erst im nächsten Superschritt wirksam, d.h. gelesene oder geschriebene Daten stehen den Prozessen erst im nächsten Superschritt zur weiteren Verarbeitung zur Verfügung. Im BSMP-Modus verfügt jeder Prozessor über einen Systempuffer bzw. über eine Warteschlange, an welche die Nachrichten verschickt werden. Über die Operation bsp_send wird ein BSMP-Paket in die Warteschlage eines Zielprozesses geschrieben. Es wird gewährleistet, dass verschickte Nachrichten vor Beginn des nächsten Super-

2

Eine einheitliche strikte Trennung von Berechnungs- und Kommunikationsphase findet sich in der Literatur nicht. Es finden sich auch Darstellungen, in welchen eine Kommunikation während der Berechnungsphase erlaubt wird, wobei jedoch die Kommunikation den gleichen Restriktionen unterworfen ist, wie in dieser Arbeit erläutert wird. Diese Arbeit stützt sich auf die verbreitetere Darstellung u.a. in [SHM96, S.3], [RR98, S.350]. Vgl. auch [Bo02, S.6].

8

schritts den Empfänger erreicht haben. Der Zugriff auf die Warteschlange geschieht über die Operation bsp_move. Neue Pakete in der Warteschlange sind ebenfalls erst wieder im nächsten Superschritt sichtbar. Über weitere Operationen lassen sich die Anzahl und die Größe der Pakete in der Warteschlange ermitteln. DRMA wird benutzt, wenn jedem Prozess die Existenz der nicht lokalen Speicherbereiche bekannt ist. BSMP eignet sich hingegen besser für Probleme, bei denen nur der Nachrichtenempfänger Kenntnis über den genauen Speicherort ankommender Daten hat. Ein Prozess beendet seine Kommunikationsphase durch den Aufruf einer Synchronisationsoperation bsp_sync und wartet solange, bis alle Nachrichten ihr Ziel erreicht haben. Sind alle Nachrichten verschickt worden, starten alle Prozessoren gemeinsam ihren nächsten Superschritt. Diesen Synchronisationsmechanismus bezeichnet man als Barriere-Synchronisation. Erst mit Beginn des neuen Superschritts werden die Effekte des Datenaustauschs für die Prozesse sichtbar. Die Dauer der Barrieresynchronisation ergibt sich aus dem Parameter l.

(virtuelle) Prozessoren P1

P2

P3

Pn-1

...

Pn

Lokale Berechnungen

Superschritt

Globale Kommunikation

Barriere-Synchronisation Zeit Abb.4: Ein Superschritt

9

Ein BSP-Rechner ist ein 2-Level-Speichermodell. Jeder Prozessor verfügt über seinen eigenen lokalen Speicher. Alle anderen Speicher sind nicht lokal. Der Zugriff auf diese kann jedoch einheitlich effizient geschehen, d.h. die Zeit für einen Datenaustausch zwischen einem lokalen und einem nicht lokalen Speicher ist unabhängig davon, auf welchen nicht lokalen Speicher zugegriffen wird. Das bedeutet, dass ein Programmierer keine Kenntnisse über die Organisation von Speicherhierarchien, basierend auf Netzwerklokalitäten in der Verbindungsstruktur des verwendeten Kommunikationsnetzwerks haben muss [ST95, S.345]. Insofern können die Kosten eines Superschritts in einem BSP-Algorithmus wie folgt abgeschätzt werden:

TSuperschritt = L + m * g * h + l

Die Kosten eines BSP-Algorithmus ergeben sich aus der Summe der Ausführungszeiten seiner benötigten Superschritte.

4.2 BSPlib-Programmierung Das BSP-Berechnungsmodell kann mehreren Programmiermodellen zugrunde gelegt werden. Es existieren verschiedene Programmbibliotheken, welche das Erstellen von effizienten BSP-Programmen unterstützen. Im folgenden soll eine kurze Einführung in die BSP-Programmierung anhand der BSPlib-Bibliothek gegeben werden. Die BSPlib ist eine der ältesten und am weitesten verbreitete BSP-Bibliothek und kann mit C, C++ und Fortran benutzt werden. Sie besteht im Kern aus nur 20 Basisoperationen zur Initialisierung, Kommunikation und Synchronisation. Die folgenden Programmbeispiele sind in der Programmiersprache C notiert. Die BSPlib adoptiert das Single Program Multiple Data (SPMD)-Programmiermodell. Die Aufgabe beim Schreiben eines SPMD-Programms beinhaltet typischerweise das Abbilden eines Problems, welches eine Datenstruktur der Größe n manipuliert, auf p Instanzen eines Programms, so dass jedes Programm n/p große Blöcke der ursprünglichen Datenstruktur bearbeitet. Dazu stellt die Bibliothek die notwendige Infrastruktur zur Verteilung der Daten und zur Kommunikation bereit. Weiterhin ermöglicht die

10

BSPlib eine architekturunabhängige Entwicklung von higher-level-Bibliotheken und Tools zum Automatisieren dieser Aufgaben.

4.2.1 Starten und Beenden von SPMD-Code Prozesse werden in einem BSPlib-Programm über die Operationen bsp_begin und bsp_end gestartet bzw. beendet. Es darf nur ein bsp_begin/bsp_end-Paar in einem Programm existieren. Der durch die Operationen eingeschlossene Code wird auf mehreren Prozessoren ausgeführt. Sind diese Operationen die erste und die letzte Anweisung im Programm, so erfolgt die Berechnung in reiner SPMD-Weise. Alternativ kann ein einzelner Prozess gestartet werden, welcher zunächst die Anzahl der benötigten parallelen Prozesse bestimmt, bevor die eigentliche parallele Berechnung ausgeführt wird. Die Syntax und die Parameter der beiden Operationen lauten wie folgt, wobei maxprocs die Anzahl der angeforderten Prozesse angibt:

void bsp_begin(int maxprocs); void bsp_end(void);

Der unten stehende Code zeigt ein triviales BSPlib-Programm. Das Programm erzeugt die maximale Anzahl an verfügbaren Prozessen, welche jeweils eine Ausgabe auf dem Bildschirm erzeugen.

void main(void) { bsp_begin(bsp_nprocs()); printf(“Hello BSP Worldwide from %d of %d\n”, bsp_pid(), maxprocs); bsp_end(); }

11

Wenn mehrere Prozesse eine Ausgabe generieren, werden diese auf dem Terminal des Benutzers gemultiplext und erscheinen in willkürlicher Reihenfolge. Nur über den Prozess null können Ein- und Ausgaben (z.B. Dateizugriffe) korrekt ausgeführt werden.

4.2.2 Simulation dynamischer Prozesse In dem bereits erwähnten alternativen Modus zum Starten von BSPlib-Prozessen wird zunächst ein einzelner Prozess gestartet, welcher die Anzahl der benötigten parallelen Prozesse bestimmt. Aus dem initialen Prozess heraus werden über bsp_begin eine entsprechende Anzahl von weiteren Prozessen erzeugt. Die Ausführung der parallelen Berechnung erfolgt in gewohnter SPMD-Manier, bis bsp_end durch alle erzeugten Prozesse aufgerufen wird. An diesem Punkt sind alle Prozesse terminiert, mit Ausnahme des erzeugenden initialen Prozesses, welcher den Rest des Programms sequenziell ausführt. Da nicht alle parallelen Maschinen dynamische Prozesserzeugung unterstützen (wie z.B. IBM SP2 oder Cray T3E), wird dieser Vorgang über die bsp_initOperation simuliert. Diese Operation erhält als Parameter eine Referenz auf eine Methode, in welcher als erstes und letztes Statement bsp_begin und bsp_end angegeben werden. Auf diese Weise wird der SPMD-Teil des Programms in einer einzelnen Methode gekapselt. Folgendes Beispiel veranschaulicht dieses Szenario:

int nprocs; /* globale Variable */

void spmd_part(void) { bsp_begin(nprocs) ; printf(“Hello BSP Worldwide from %d of %d\n”, bsp_pid(), maxprocs); bsp_end(); }

void main(int argc, char *argv[]) { bsp_init(spmd_part, argc, argv); nprogs = ReadInteger(); /* Tastatureingabe */

12

spmd_part(); }

4.2.3 Stoppen der Programmausführung Die Funktion bsp_abort bietet eine einfache Möglichkeit der Fehlerbehandlung. Tritt in einem Prozess eine Fehlersituation auf, so kann über bsp_abort eine Fehlermeldung ausgegeben werden. Nach der Ausgabe der entsprechenden Fehlermeldung wird das BSPlib-Programm angehalten, d.h. alle Prozesse werden auf der Stelle beendet, ohne dass eine Barriere-Synchronisation erforderlich ist. Die Syntax dieser Operation lautet:

void bsp_abort(char *format...);

Das Format des übergebenen Parameters entspricht dem des printf-Befehls.

4.2.4 Lokale Abfragefunktionen BSPlib-Abfragefunktionen erfordern keine Kommunikation zwischen den Prozessen. Sie liefern Informationen bezüglich der Anzahl der an der Berechnung beteiligten parallelen Prozesse, der ProzessID eines SPMD-Prozesses und der vergangenen Zeit in Sekunden seit bsp_begin. Folgende Abfragefunktionen werden durch die BSPlib bereitgestellt:

int bsp_nprocs(void); int bsp_pid(void); double bsp_time(void);

Wird die Funktion bsp_nprocs vor bsp_begin aufgerufen, dann liefert sie die maximale Anzahl der verfügbaren Prozessoren zurück. Wird sie innerhalb des 13

bsp_begin/bsp_end-Blocks aufgerufen, dann benennt sie die Anzahl der aktiven Prozesse.

4.2.5 Superschritte Während eines Superschritts können mehrere Berechnungen auf zu Beginn des Superschritts lokal gehaltene Daten ausgeführt werden. Das Ende des einen und der Beginn des folgenden Superschritts wird durch Aufruf der Bibliotheksfunktion bsp_sync gekennzeichnet. Die Syntax lautet:

void bsp_sync(void);

4.2.6 Kommunikation Ein grober Überblick über die Operationen und den Ablauf des Direct Remote Memory Access und Bulk Synchronous Message Passing wurde bereits im Kapitel 4.1 gegeben. Aus diesem Grund wird an dieser Stelle auf eine tiefergehende Betrachtung dieser Kommunikationsmodi verzichtet. Statt dessen wird exemplarisch der Ablauf der DRMA-Kommunikation an einem Code-Beispiel gezeigt. Für weitere Informationen sei auf [HMS98] verwiesen.

Die Syntax der benötigten Registrierungs- und Kommunikationsoperationen:

void bsp_push_reg(const void *ident, int size); void bsp_pop_reg(const void *ident);

ident ist eine bereits initialisierte Variable, welche die Adresse des zu registrierenden lokalen Speicherbereichs hält. size gibt die Größe des zu registrierenden Speicherbereichs an.

void bsp_put(int pid, const void *src, void *dst,

14

int offset, int nbytes);

pid ist die ID des Zielprozesses. src ist die Quelladresse des ersten zu transferierenden Bytes. dst ist die Zieladresse, an welcher die Daten abgelegt werden. offset wird zur Zieladresse addiert. nbytes ist die Anzahl der zu transferierenden Bytes.

Die unten angegebene reverse-Funktion zeigt die Interaktion zwischen der Registrierung und der Kommunikation über die bsp_put-Operation. Das Beispiel zeigt eine einfache Kommunikation zwischen denjenigen Prozessen, welche die reverseFunktion im gleichen Superschritt ausführen. Zu beachten ist, dass der Effekt der bsp_put-Operation, also das Überschreiben der Variable x durch einen anderen Prozess, erst mit dem Beenden des zweiten Superschritts wirksam wird. Dadurch ist gewährleistet, dass jeder Prozess den Inhalt seiner lokalen Variable transferieren kann, bevor dieser durch den DRMA-Zugriff eines anderen Prozesses manipuliert wird. Als Rückgabewert liefert diese Funktion den im Rahmen des Transfers empfangenen Wert der Variable x zurück.

int reverse(int x) { /* registriere x für DRMA-Zugriff */ bsp_push_reg(&x, sizeof(int)); bsp_sync(); /* --Ende des ersten Superschritts-- */

/* transferiere x */ bsp_put(bsp_nprocs()-bsp_pid()-1, &x, &x, 0, sizeof(int)); bsp_sync();

15

/* --Ende des zweiten Superschritts-- */

/* hebe DRMA-Registrierung auf */ bsp_pop_reg(&x); return x; }

4.3 Diskussion des BSP-Modells und seiner Varianten Das BSP-Kostenmodell wird aufgrund seiner Einfachheit oft zur Bewertung von Algorithmen herangezogen. Untersuchungen haben jedoch gezeigt, dass das BSP-Modell nicht immer gute Vorhersagen der Laufzeit von Algorithmen ermöglicht. Dieses Problem ergibt sich aufgrund der Tatsache, dass bei vielen Parallelrechnern und vor allem bei Clustern von Computern die maximale Bandbreite erst erreicht wird, wenn die Nachrichten eine bestimmte Größe haben. Bei kleinen Nachrichten kann durch die verwendete Software und der eingesetzten Protokolle ein exorbitanter Overhead entstehen. Dieser ergibt sich unter anderem aus dem Zusammenstellen von Nachrichten, Funktions- und Betriebssystemaufrufen oder dem Versehen von Nachrichten mit zusätzlichen Headern (vgl. TCP/IP-Protokollstack) [Bo02, S.8]. Um dieses zu modellieren, wurde in [BDM98] als Erweiterung das BSP*-Modell vorgeschlagen, welches einen zusätzlichen Parameter B einbezieht, der die minimale Nachrichtengröße angibt, mit welcher die Kommunikation effizient abläuft. Es ist weiterhin als Nachteil festzustellen, dass das BSP-Modell die Lokalität unberücksichtigt lässt, d.h. das Versenden einer Nachricht zu einem benachbarten Prozessor wird mit der gleichen Zeit angesetzt wie das Versenden einer Nachricht zu einem weit entfernten Prozessor. Außerdem berücksichtigt das BSP-Modell das parallele Ausführen von zwei verschiedenen Algorithmen nicht, da beide Algorithmen die gleichen Synchronisationen ausführen müssen. Das D-BSP-Modell (decomposible), vorgeschlagen von de la Torre und Kruskal, beseitigt diesen Makel. Es erlaubt, den BSP-Computer in mehrere autonome Teilcomputer zu partitionieren. Innerhalb ihrer Prozessormengen können beliebig Nachrichten ausgetauscht werden und Synchronisationen erfolgen [Bo02, S.8f]. 16

Als problematisch anzumerken bleibt, dass die Laufzeit der im BSP-Modell entwickelten Algorithmen abhängig von den BSP-Parametern und damit von der Hardware der eingesetzten Maschine ist, d.h. ein Algorithmus ist auf unterschiedlichen Parallelrechnern nicht gleich effizient. Je nach Problemstellung und Plattform ist es also notwendig, den einzusetzenden Algorithmus sorgfältig auszuwählen. In [Bo02] wird ein System zur automatischen Konfiguration effizienter paralleler Algorithmen im BSP-Modell vorgeschlagen. Als Vorteil ist die durch die BSP-Bibliotheken (z.B. BSPlib oder JBSP) gegebene Plattformunabhängigkeit zu nennen. Hierdurch wird nicht nur das Ziel der Portabilität, sondern auch das der Skalierbarkeit der entwickelten Software erfüllt. Eine Weiterführung dieses Gedankens findet sich in [CFSV95]. Im Vergleich zum PRAM-Modell ist positiv zu bewerten, dass ein Algorithmus in der Regel deutlich weniger Kommunikationsaufkommen als lokale Berechnungen aufweist und dass Prozessoren nur selten synchronisiert werden müssen. Als Vorteil des BSPModells ist weiterhin festzustellen, dass durch die Entkopplung von Berechnung und Kommunikation keine Deadlocks auftreten können.

4.4 BSP in der Praxis Als Beispiel für den praktischen Einsatz der Programmierung im BSP-Modell sei die Auswertung von Programmen genannt, welche in einer reinfunktionalen Programmiersprache formuliert wurden. Diese Programme eignen sich deshalb in hohem Maße dazu, parallel ausgeführt zu werden, weil sie ohne Zustandsvariablen auskommen und nebeneffektfrei sind. Teilausdrücke können daher unabhängig voneinander ausgewertet werden. Frédéric Loulergue hat viel Forschungsarbeit auf diesem Gebiet geleistet und unter anderem die BSMLlib, einer BSP-Bibliothek zur Auswertung von Caml-Programmen entwickelt. Caml ist eine streng typisierte funktionale Programmiersprache aus der MLFamilie. Eines seiner aktuellen Forschungsprojekte ist CARAML. Einen Überblick über seine Arbeiten findet sich unter [Lou]. BSP wird hauptsächlich für wissenschaftliche Berechnungen eingesetzt. Ein großes Anwendungsgebiet findet sich in der Luft- und Raumfahrt, dort unter anderem in der 17

Simulation von Luftströmen. Einen kleinen Überblick über BSP-Projekte vermittelt [SHM96, S.9f].

5 Fazit Damit sich die Soft- und Hardwareindustrie auf dem Sektor der Parallelrechner ähnlich entwickeln kann wie in dem Bereich der sequentiellen Rechner, ist es unabdingbar, dass sich die Industrie bei der Entwicklung von Soft- und Hardware an einem einheitlichen und allgemein anerkannten Modell orientiert. In dieser Arbeit wurden zwei solcher Modelle, das PRAM- und das BSP-Modell vorgestellt. Es wurde festgestellt, dass das PRAM-Modell zwar ein einfaches Programmiermodell zur Verfügung stellt, aber Schwächen bei der Laufzeitanalyse von parallelen Algorithmen birgt. Performanceeinbußen ergeben sich durch hohen Kommunikations- und Synchronisationsbedarf. Die Darstellung des BSP-Modells hat ergeben, dass bei einem vergleichbar einfachem Programmiermodell eine teure Kommunikation und Synchronisation vermeidbar ist und die Ziele der universellen parallelen Berechnung, nämlich Skalierbarkeit, Portabilität und Vorhersagbarkeit, in hohem Maße erfüllt werden.

18

6 Literaturverzeichnis [BDM98] Bäumker, Armin, Wolfgang Dittrich and Friedhelm Meyer auf der Heide: Truly Efficient Parallel Algorithms: 1-optimal Multisearch for an Extension of the BSP Model, Theoretical Computer Science, Vol. 203, Nr.2, S.175203, 1998. [Bo02]

Olaf Bonorden: Ein System zur automatischen Konfiguration effizienter paralleler Algorithmen im BSP-Modell, Diplomarbeit, Universität Paderborn, 2002. Download: http://www.upb.de/cs/bono.html

[CFSV95] Thomas Cheatham, Amr, Fahmy, Dan C. Stefanescu, Leslie G. Valiant: Bulk Synchronous Parallel Computing – A Paradigm for Transportable Software, Aiken Computation Laboratory, Havard University, 1995 [GBW01] Gu Yan, Bu-Sung Lee, Wentong Cai: JBSP: A BSP Programming Library in Java, Nanyang Technological University, Singapore 639798, 2001. [Gu99]

Gu Yan: JBSP: A BSP Programming Library in Java, Nanyang Technological University, 1999.

[HMS98] J.M.D. Hill, B. McColl, D.C. Stefanescu, M.W. Goudreau, K. Lang, S. B. Rao, T. Suel, T. Tsantilas, R.H. Bisseling: BSPlib: The BSP Programming Library, 1998 [Lou]

http://f.loulergue.free.fr/research/main.html

[RR98]

T. Rauber, G. Rünger: Parallele und verteilte Programmierung, Kapitel 6.5.2., Springer, 1998.

[Sch98]

Christian Schweer: Simulation von PRAM-Programmen, Diplomarbeit, Institut für Informatik, Universität Hannover, 1998.

[SHM96] D.B. Skillicorn, Jonathan M.D. Hill, W.F. McColl: Questions and Answers about BSP, PGR-TR-15-96, Oxford University Computing Laboratory, 1996 [ST95]

David B. Skillicorn, Domenico Talia: Programming Languages for Parallel Processing, IEEE Computer Society Press, S. 335-357, 1995.

[Va90]

Leslie Valiant: A Bridging Model for Parallel Computation, Communications of the ACM, 33(8), S. 103-111, 1990

Suggest Documents