Parallele Programmierung
- Spezifiziert:
- wie Teile des Programms parallel abgearbeitet werden,
- wie Informationen ausgetauscht werden
- welche Synchronisationsoperationen verfügbar sind, um die Aktivitäten zu koordinieren
- Üblicherweise implementiert als Erweiterungen einer höheren Programmiersprache
Aufteilung der Arbeit (work partitioning)
- Identifizieren der Teilaufgaben, die parallel ausgeführt und auf die Prozessoren verteilt werden können
- Das parallele Programm ist konform zur sequentiellen Semantik
- Zwei Programmsegmente S1 und S2, die in einem sequentiellen Programm nacheinander ausgeführt werden, können parallel ausgeführt werden, wenn S1 unabhängig von S2 ist
- Thread/Prozess: Code , der auf einem Prozessor oder Prozessorkern eines Multiprozessors ausgeführt wird
Datenparallelismus (data-level parallelism)
Berechnungen von verschiedenen Datenelementen sind unabhängig (Feld,
Matrix)
- Beispiel: Matrixmultiplikation
Single Program Multiple Data (SPMD)
Eine Berechnung (eine Funktion) wird auf alle Datenelemente eines Feldes ausgeführt
Skalierung der Problemgröße
Funktionsparallelismus (function-level-parallelism, task-level parallelism)
- Unabhängige Funktionen werden auf verschiedenen Prozessoren ausgeführt
Koordination (coordination)
- Parallel auf den verschiedenen Prozessoren laufende Threads müssen koordiniert werden, so dass das Ergebnis dasselbe ist wie bei einem entsprechenden sequentiellen Programm
- Synchronisation und Kommunikation
- Austausch von Informationen über gemeinsamem Speicher oder über explizite Nachrichten
- Zusätzlicher Zeitaufwand hat Auswirkung auf die Ausführungszeit des parallelen Programms
Gemeinsamer Speicher (Shared Memory)
- Kommunikation und Koordination von Prozessen (Threads) über gemeinsame Variablen und Zeiger, die gemeinsame Adressen referenzieren
- Kommunikationsarchitektur
- Verwendung konventioneller Speicheroperationen für die Kommunikation über gemeinsame Adressen
- Atomare Synchronisationsoperationen!
![截屏2020-07-10 22.30.42](https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/截屏2020-07-10%2022.30.42.png)
Shared-Memory-Programmiermodell: Primitive
Name | Syntax | Fumktion |
---|---|---|
CREATE | CREATE(p,proc,args) | Generiere Prozess, der die Ausführung bei der Prozedur proc mit den Argumenten args startet |
G_MALLOC | G_MALLOC(size) | Allokation eines gemeinsamen Datenbereichs der Größe size Bytes |
LOCK | LOCK(name) | Fordere wechselseitigen exklusiven Zugriff an |
UNLOCK | UNLOCK(name) | Fordere wechselseitigen exklusiven Zugriff an |
BARRIER | BARRIER(name,number) | Globale Synchronisation für number Prozesse |
WAIT_FOR_END | WAIT_FOR_END(number) | warten. bis number PRozesse terminieren |
WAIT_FOR_FLAG | while (!flag); or WAIT(flag) | Warte auf gesetztes flag; entweder wiederholte Abfrage (spin) oder blockiere; |
SET FLAG | flag=1; or SIGNAL(flag) | Setze flag; weckt Prozess auf, der flag wiederholt abfragt |
Nachrichtenorientiertes Programmiermodell (Message Passing)
Kommunikation der Prozesse (Threads) mit Hilfe von Nachrichten
- KEIN gemeinsamer Adressbereich
Kommunikationsarchitektur
Verwendung von korrespondierenden Send- und Receive-Operationen
Send: Spezifikation eines lokalen Datenpuffers und eines Empfangsprozesses (auf einem entfernten Prozessor)
SEND(src_addr, size, dest, tag)
Receive: Spezifikation des Sende-Prozesses und eines lokalen Datenpuffers, in den die Daten ankommen
RECEIVE(buffer_addr, size,src,tag)
![截屏2020-07-10 22.35.07](https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/截屏2020-07-10%2022.35.07.png)
Message Passing: Primitive
Name | Syntax | Funktion |
---|---|---|
CREATE | CREATE(procedure) | Erzeuge Prozess, der bei procedure startet |
SEND | SEND(src_addr,size,d est,tag) | Sende size Bytes von Adresse src_addr an dest Prozess mit tag Identifier |
RECEIVE | RECEIVE(buffer_addr, size,src,tag) | Empfange eine Nachricht mit der Kennung tag vom src -Prozess und lege size Bytes in Puffer bei buffer_addr ab |
BARRIER | BARRIER(name,number) | Globale Synchronisation von number Prozessen |