Fallbeispiel: Poisson-Gleichung
poisson1 (
Source
):
Aufgabenstellung:
Finde approximative Lösung der Poisson-Gleichung
auf einem rechteckigen Gitter für gegebene Quellen f und Randwerte u
Bemerkungen:
Kontinuum ersetzt durch Gitter, Lösung durch Jacobi-Iteration:
Beispiel-Quelle: "elektronische Linse"
Implementierung mit zwei U-Matrizen im Wechsel (vermeidet Umkopieren)
Es gibt wesentlich bessere Algorithmen (SOR, Multigrid)!
poisson2 (
Source
):
Parallelisierung:
PARALLEL
um it-Schleife,
DO
um sweep-Schleife
Synchronisierung:
Barriers zwischen den sweep-Läufen nötig
automatisch durch
END DO
Datenlokalisierung:
Variable in sweep (incl. sweep) automatisch privat
it
privat, daher nach
END PARALLEL
nicht verfügbar
(
LASTPRIVATE
geht nur bei
DO
)
Lösung: print als
SINGLE
-Block in den parallel-Block
error: privat (mehrfacher Schreibzugriff)
Problem: error enthält nur den threadeigenen Fehler-Anteil
Werte für error in jedem Thread verschieden
Abbruch klappt nicht, Deadlock möglich (z.B. bei n=20)
poisson3 (
Source
):
globales Abbruch-Kriterium nötig
Aufsummierung von error zu (shared) total_error
REDUCTION
bei
PARALLEL
geht nicht, da die Aufsummierung erst am Ende des
PARALLEL
-Blocks erfolgt
REDUCTION
bei
DO
in sweep geht nicht, da der Returnwert wie alle lokalen Variablen in sweep thread-privat ist.
Initialisierung von total_error in
SINGLE
Summation mit
CRITICAL
:
nur ein Thread im kritischen Bereich
alle Threads laufen - nacheinander - durch
Serieller Bereich muß klein sein, sonst Performance-Problem
BARRIER
vor dem Test von total_error
poisson4 (
Source
):
Ziel: sweep gibt Gesamtfehler zurück, Hauptprogramm einfach
Problem: alle Variablen in sweep sind lokal
Lösung: Variable in extra Module (oder auch
COMMON
-Block) sind shared
Rest wie vorher, aber versteckt in sweep
Peter Junglas 16.2.1999