99
Parallelprogrammierung mit der TPL und .NET 4.0 Bernd Marquardt – bm@go- sky.de

Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – [email protected]

Embed Size (px)

Citation preview

Page 1: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Parallelprogrammierung mit der TPL und .NET 4.0

Bernd Marquardt – [email protected]

Page 2: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Agenda

EinführungSchleifen parallelisierenCode-Bereiche parallelisierenAufgaben parallelisierenWeitere spezielle Themen

PLINQ, Exceptions, Cancelation, Containerklassen

Testen und DebuggenWindows und ParallelprogrammierungZusammenfassung

Page 3: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Einführung

Bisher:Alle 2-3 Jahre wurden die CPU‘s doppelt so schnell

Davon haben unsere Programme automatisch etwasDeutlich sichtbar bei mathematischen Berechnungen, weniger sichtbar bei UI-Angelegenheiten

Page 4: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Einführung

Intel Clock SpeedQuelle: Intel, Wikipedia

Page 5: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Einführung

Prozessor-Takt bleibt bei 3 – 4 GHz stehen

Mehr geht nicht: Kühlung wird schwierigEigentlich müssten unsere CPU‘s jetzt ca. 100 GHz können

Anzahl der Transistoren auf einem Chip steigt aber weiter an

Resultat: Multi-Core CPU‘s kommen immer stärkerMehrere CPU‘s auf einem Chip

Page 6: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Einführung

Programmierung für Multi-Core CPU‘s Multi-Processing (gibt uns das Betriebssystem)Multi-Threading (müssen wir im Moment noch selbst programmieren)

Wir müssen unsere Programme anpassen, sonst haben wir nichts von dem Multi-Core CPU‘s in einer Anwendung

Page 7: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

EinführungAndere Parallelisierungs-Technologien:

Multithreading, ThreadpoolManaged und unmanaged Code

OpenMP (C, C++)Managed und unmanaged Code

MPI (Message Passing Interface) (C, C++, FORTRAN)

Jetzt auch managed für .NET MPI.NET

NEU: Parallel Extensions for .NET (TPL)Eine Erweiterung für C# und VB.NETNur managed Code

NEU: Parallel Pattern Library (PPL)Eine Erweiterung für C++ in VS 2010Nur native Code

Page 8: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Einführung

ACHTUNG:

Normale Multithread-Programmierung ist NICHT einfach!

Höherer AufwandDebuggingFehlersucheTestingSynchronisierungPlanung

Page 9: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

(1-P

)P

Tse

rial

(1-P

)

P/2n = number of processorsn = number of processors

Tparallel = {(1-P) + P/n} Tserial

Speedup = Tserial / Tparallel

0.5 + 0.25

1.0/0.75 = 1.33

n = 2n = ∞

P/∞

0.5 + 0.0

1.0/0.5 = 2.0

Sequentieller Code begrenzt das Speedup!

+ O

Einführung – Amdahls Gesetz

Page 10: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Einführung – Amdahls Gesetz

Dies bedeutet, dass die parallelen Arbeitseinheiten groß genug sein müssenAnsonsten dauert die Thread-Initialisierung länger, als die Parallelisierung einbringt

Page 11: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Installation

Nur Visual Studio 2010/.NET 4.0 NICHT mit VS 2008 (CLR 4 wird benötigt)

Betriebssysteme:Windows Server 2003/2008/2008 R2Windows XPWindows VistaWindows 7

Page 12: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Einführung

Die TPL nutzt Threads aus dem .NET-ThreadPoolThreads aus dem ThreadPool bedeutet:

Schnelle Bereitstellung von ThreadsDadurch sind auch kleinere Aufgaben gut zu parallelisierenDie Threads müssen aber an den Pool zurückgegeben werden

Page 13: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

TestThreadPool

demo

Page 14: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Parallelerweiterungen für LinqEs gibt zwei Möglichkeiten:

System.Linq.ParallelEnumerable-KlasseAsParallel-Erweiterungsmethode

Ziel: Parallele Datenabfragen mit LinqSehr einfachWAS-Programmierung statt WIE-Programmierung

Page 15: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo 3, ParallelBabyNames

demo

Page 16: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Schleifen parallelisieren

Wichtige Klasse:System.Threading.Tasks.Parallel

Schleifen werden aufgeteilt auf mehrere Threads aus dem ThreadPoolDas geht nur, wenn die einzelnen Schleifendurchläufe unabhängig voneinander sind

Problem z.B.: a[i] = a[i – 1] * 2

Page 17: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Schleifen parallelisieren

WICHTIG:„Nach“ der Schleife werden alle Threads synchronisiert, welche die Schleife abgearbeitet habenIn der Schleife können Variablen deklariert werden, die „thread-local“ sindDie Laufvariable darf nicht als lokale Variable deklariert werden

Page 18: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo 4, Demo 5, Demo 6

demo

Page 19: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Schleifen parallelisieren

Auch foreach-Schleifen können parallelisiert werdenDie Reihenfolge der Schleifendurchläufe ist nicht deterministisch

Page 20: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo 4A

demo

Page 21: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Schleifen parallelisieren

Achtung: Bei „unausgewogenen“ Schleifen muss etwas mehr in der Bibliothek passierenBeispiel:

for(int i = 0; i < 1000; i++){ if(i < 500) { DoLongCalculation(); } else { DoShortCalculation(); }}

Page 22: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Schleifen parallelisieren

Diese Schleife wird nicht „halbiert“Es werden kleine Arbeitseinheiten gemachtSobald ein Thread mit einer Arbeitseinheit fertig ist, bekommt er die nächste, bis die Arbeit komplett erledigt ist Schleifen-PartitionierungDas implementierte Standard-Verfahren ist sehr leistungsfähig

Page 23: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Schleifen: Eigene Partitionierung

Man kann eigene Partitionierungsverfahren implementierenInteressant, bei Schleifen mit…

…sehr kleinem Schleifen-Body…extrem unausgewogenen Schleifen

Performance ist abhängig von einer vernünftigen Schleifen-Partitionierung

Page 24: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Partitioner

demo

Page 25: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Probleme mit Schleifen

Achtung bei schreibendem Zugriff auf Klassenvariablen oder statischen Variablen

Keine Fehlermeldungen (vom Compiler, Runtime)Ergebnisse sind falsch ( „Data Race“)

REGEL: Es darf nur ein Thread gleichzeitig schreibend zugreifenGgf. synchronisieren, d.h., schreibende Zugriffe werden nacheinander abgewickeltAchtung: Performance!

Page 26: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Probleme mit Schleifen

Schleifendurchläufe sind nicht unabhängig voneinanderD.h., in Schleifendurchlauf #i wird auf Daten zugegriffen, die im Schleifendurchlauf #j berechnet werden, wobei gilt: i != jZ.B.: a[i] = a[i-1] + 1Abhilfe: Den Algorithmus ändern

Werte, die in der Schleife benötigt werden, möglichst aus dem Index berechnen

Page 27: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Aggregationen

Zusammenfassen von ErgebnissenAchtung: Meistens ist Locking erforderlichTypischer Anwendungsfall:double dSum = 0.0;

for(int i = 0; i < 1000; i++){ dSum += Math.Sqrt(i);}

Page 28: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Aggregationen

Zwischenwerte werden über den sog. ThreadLocalState weitergegebenAblauf:

Vor der Schleifenabarbeitung: LocalState initialisierenSchleifenteil abarbeiten: Im Thread rechnen, LocalState benutzenNach der Abarbeitung der Teilschleife: Aggregation (Zusammenfassung) der Ergebnisse (Achtung: Locking!!!)

Page 29: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Aggregationen

Das Ziel ist, möglichst WENIG Locking-Operationen durchzuführenMöglichkeit #1: In jedem Schleifendurchlauf beim Zugriff (Addition) auf dSum findet ein Lock stattMöglichkeit #2: Zwischensumme einer Arbeitseinheit ermitteln, Zwischensumme mit Locking zu dSum addieren

Page 30: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Aggregationen

int iSum = 0;

Parallel.For(0, 1000, // From, To () => 0, // Init// (Laufvariable, ParallelLoopState, ThreadLocalState) (i, pls, tls) => { // Loop body tls += i; return tls; }, (partSum) => { // Aggregation Interlocked.Add(ref iSum, partSum); });

Page 31: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Agg1, Agg2

demo

Page 32: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Schleifen abbrechen

Wenn mehrere Threads für die Schleife parallel laufen, dann müssen alle Threads beendet werdenKlasse ParallelLoopResult benutzen

Berechnung beendet?

Klasse ParallelLoopState enthält Break-Methode und eine Stop-Methode

Alle Threads werden beendet

Page 33: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

LoopBreakTest

demo

Page 34: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Tipps und Tricks

Parallel.For und Parallel.ForEach:(Anzahl der Durchläufe * Dauer) muss groß genug sein

Nicht vergessen: Amdahl‘s Gesetz!Möglichst wenig Synchronisierung verwenden

Page 35: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Beispiele und PerformanceInnere und äußere SchleifeSchleifendurchläufe mit stark unterschiedlicher DauerMatrixmultiplikationPrimzahlen berechnen

Page 36: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

InnerOuter, MatMult,PrimeSeq, PrimePar

demo

Page 37: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Performance MatMult (2 Core)Größe Sequentiell

Parallel5 0.0017 0.0223 ms10 0.0111 0.0254 ms25 0.1687 0.1830 ms50 1.3953

1.2970 ms100 11.207 9.300 ms250 185.41 94.81 ms500 1950.8 978.0 ms

Page 38: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Anzahl der Threads

Die Anzahl der zu verwendenden Threads wird mit der ParallelOptions–Klasse definiertMaxDegreeOfParallelism = -1 Alle Kerne und Prozessoren werden ausgenutztIn bestimmten Fällen kann es auch sinnvoll sein, die Anzahl der benutzten Threads auf > Kerne * Prozessoren zu setzen

Page 39: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo2010_1

demo

Page 40: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Codeblöcke parallelisieren

Unabhängiger Code kann parallel ausgeführt werdenHäufigstes Problem: Gleichzeitiger Zugriff auf die gleichen Daten (schreibend)Ohne Nachdenken geht da gar nichts!Wichtige Methode: Parallel.InvokeAuch hier: Unterschiedliche

Schreibweisen möglich…

Page 41: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo 7, Demo 8

demo

Page 42: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Die Klasse Task

Die Task-Klasse wird benötigt, um erweiterte Parallelisierungprobleme zu lösenVergleichbar mit der ThreadPool-Klasse:

…ist ähnlich wie:

ThreadPool.QueueUserWorkItem(delegate { … });

Task.Factory.StartNew(delegate { … });

Page 43: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Tasks

Die TPL benutzt nun den .NET ThreadPool als Standard-SchedulerDer ThreadPool hat mehrere Vorteile:

Work-stealing queues werden intern in der TPL benutztHill-climbing-Methoden, wurden eingeführt, um die optimale Thread-Anzahl zu ermittelnSynchronisierungsmechanismen (wie SpinWait und SpinLock) werden intern verwendet

Page 44: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Tasks: WSQ

Page 45: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Die Klasse Task

Wichtige Features:Synchronisierung von parallelen Ausführungseinheiten

Task.Wait(), WaitAll(), WaitAny()

Abbrechen von Ausführungseinheiten Cancelation Framework

Page 46: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo 10, Demo 11

demo

Page 47: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Tasks und Parameter

Übergabe von Parametern im Funktionsaufruf möglichAchtung: Seiteneffekte, wenn man es falsch machtÜbergabe der Parameter mit Parametern der Lambda-Funktion

Page 48: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo 12_Falsch, Demo 12_Correct

demo

Page 49: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Task-Parameter

Tasks können kontrolliert werden……Created…WaitingForActivation…WaitingToRun…RanToCompletion…Canceled…Faulted…WaitingForChildrenToComplete

Page 50: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Tasks in Schleifen

Tasks sind gut in sehr unausgewogenen Schleifen

for(int i = 0; i < n; i++){ for(int j = 0; j < i; j++) { for(int k = 0; k < i; k++) { for(int l = 0; l < k; l++) { // Do Work… } } }}

Page 51: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Tasks in Schleifen

Lösung 1: Schleife (außen) mit Parallel.For parallelisierenAchtung: Die Schleifendurchläufe werden zum Schluss immer länger

Der Scheduler kann die Teilschleifen nur schlecht aufteilen, so dass alle Prozessoren gleichmäßig ausgelastet sind

Lösung: Schleifen „rückwärts“ laufen lassen und Tasks benutzen (Task mit dem beiden inneren Schleifen)

Page 52: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

MuchLoops, MuchLoopsTask

demo

Page 53: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Die Klasse Task<TResult>

Die Klasse ermöglicht die asynchrone Berechnung von Daten

Wenn später dann die berechneten Daten weiter benutzt werden sollen, wird geprüft, ob die Berechnung bereits abgeschlossen istSonst wird gewartet…. = Synchronisierung

Kann man Task<TResult>-Variablen in Anwendungen mit einer Benutzerschnittstelle benutzen?

Page 54: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo 13, Demo 14, FutureWinForms, …WPF,FutureWinForms2, …LINQ

demo

Page 55: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Concurrent Exceptions

In normalen, sequentiellen Anwendungen kann zu einer bestimmten Zeit maximal EINE Exception geworfen werdenBei parallelen Anwendungen können auch mehrere Exceptions zu einem Zeitpunkt geworfen werdenOft werden die Exceptions dann auch noch in einem anderen Thread verarbeitet, als in dem Thread, in dem sie geworfen wurden

Page 56: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Concurrent Exceptions

Paralleler Code:Reihenfolge, mehrere Exceptions!!

Darum gibt es einen anderen Exception-Mechanismus in den Parallel Extensions Wenn eine Exception im Parallel-Code auftritt, werden alle Threads - so schnell wie möglich - angehaltenAchtung: In dieser Zeit können eventuell noch weitere Exceptions auftreten!

Page 57: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Concurrent Exceptions

Alle aufgetretenen Exceptions werden in einem Objekt der Klasse System.Threading.AggregateException eingesammeltWenn alle Threads angehalten sind, dann wird die AggregateException neu geworfen und kann bearbeitet werdenDie einzelnen Exceptions können über das Property InnerExceptions abgefragt werden (eine Collection der aufgetretenen Exceptions)

Page 58: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Concurrent Exceptions

Welche Klassen werfen AggregateException-Objekte?

Die Parallel-KlasseDie Task-KlasseDie Task<TResult>-KlasseParallel LINQ (Abfragen)

Page 59: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo 15

demo

Page 60: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Synchronisierung

Die Synchronisierung soll den Zugriff auf begrenzte Resourcen des Rechners steuern, wenn mehrere Threads gleichzeitig darauf zugreifen wollen

Variablen (RAM)CodeteileLPT-, COM- und USB-Schnittstellen

Page 61: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Synchronisierung

Eine Synchronisierung beinhaltet immer die Gefahr eines „Deadlocks“

Thread A wartetauf dieResource

Thread B hat dieResource inBenutzung

Thread B wartetauf Thread A

Page 62: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Synchronisierung

Allgemeine Regeln:

Nicht zu viel synchronisieren LangsamNicht zu wenig synchronisieren FalschDie richtige Sychronisierungsmethode wählenKeine eigenen Synchronisierungselemente programmieren Schwierig

Page 63: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Synchronisierung

Standard-Synchronisierungsmechanismen:

Monitor, lock (C#)Interlocked-KlasseMutexWaitHandle

Page 64: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Synchronisierung

BarrierCountDownEventLazyInit<T>ManualResetEventSlimSemaphoreSlimSpinLockSpinWaitWriteOnce<T>Collections (Stack, Queue, Dictionary)

Page 65: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

ConcurQueue

demo

Page 66: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

TPL + UI

Die goldene Regel gilt natürlich auch hier!WPF oder WinForms laufen im STASie dürfen nur aus dem Thread auf Controls zugreifen, im dem Sie die Controls erzeugt habenAb Framework 2.0: Exception im Debug-Modus

Page 67: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

TestWinForms

demo

Page 68: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

TPL + UI

WindowsForms:Benutzung von InvokeRequired zum Test, ob der richtige ThreadBenutzung von BeginInvoke zum Umschalten in den richtigen Thread

Windows Presentation Foundation:Benutzung von Dispatcher.VerifyAccess oder Dispatcher.CheckAccess zum Test, ob der richtige ThreadBenutzung von Dispatcher.Invoke zum Umschalten in den richtigen Thread

Page 69: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

TestTPLWinForms

demo

Page 70: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Erweiterung der Tasks

Erweiterungen zusätzlich zu ContinueWith:ContinueWhenAllContinueWhenAnyLeistungsfähiges Konzept für die Fortführung der Arbeit, wenn bestimmte Teilaufgaben erledigt sind

Page 71: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

TaskScheduler

Die alte Klasse TaskManager wurde ersetzt durch die TaskScheduler-Klasse

Neue WorkStealing-Queues im ThreadPool

TaskScheduler ist eine abstrakte Basisklasse

Man kann davon ableiten und eigene TaskScheduler‘s programmierenInteressant für spezielle Szenarien

Z.B.: spezielle Prioritätsverwaltung

Page 72: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

TaskSchedulerTest

demo

Page 73: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

TaskScheduler

Ein weiteres spezielles Szenario für die Benutzung eines TaskScheduler‘s:Zugriff auf das User Interface

Die alte Regel gilt immer noch…

Ablauf:Asynchrone Berechnung im TaskFortführung mit ContinueWith (z.B. Ergebnisausgabe) – aber im korrekten Thread-Kontext ( im UI-Thread)

Früher: Benutzung von Invoke

Page 74: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Demo2010_Scheduler

demo

Page 75: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Cancellation

Einfaches „Abschießen“ (Kill) von Threads ist keine gute Lösung

Offene Dateien???Locks???Schreibende Zugriffe???Genutzte Resourcen???…???

Page 76: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Cancellation

Das Beenden von Threads muss kooperativ erfolgen

Der Thread kann nur an bestimmten Stellen beendet werdenDer Thread kann selbst entscheiden, wann er beendet wirdAbhängige Threads werden ebenfalls beendet

Gutes Beispiel: BackgroundWorker-Control (ab .NET Framework 2.0)

Page 77: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Cancellation

Anlegen eines CancellationTokenSource-ObjektesDas CancellationToken-Objekt wird an alle Threads übergeben, die über das eine Source-Objekt beendet werden könnenIn den Threads wird das Token-Objekt über das Property IsCancellationRequested abgefragtAlle Threads des Source-Objekts werden über die Cancel-Methode des Source-Objektes beendet

Page 78: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Cancellation

Ggf. wird dann aufgeräumtNach dem Aufräumen wird aus dem Thread eine OperationCanceledException geworfenDiese kann im aufrufenden (Main-) Thread eingefangen und verarbeitet werden

Page 79: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

CancelTest1, TaskCancel

demo

Page 80: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Testen und Debuggen

…ist in parallelen Programmen gar nicht so einfachParallelprogrammierung hat meistens einen Grund: Performance-SteigerungMessgrößen sind also:

Richtigkeit des ErgebnissesAusführungszeit

Page 81: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Testen und Debuggen

Häufiges Problem:Die Anwendung skaliert nicht mehr mit Erhöhung der Prozessoranzahl

0

2

4

6

8

10

12

1 2 3 4 5 6 7 8 9 10 11 12

Zeit

Page 82: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Testen und DebuggenPerformance-Tests mit Visual Studio

Page 83: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Visual Studio: TestPerf

demo

Page 84: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Debugging

Es gibt zwei neue Debugging-Fenster in Visual Studio 2010

Fenster: Parallel TasksFenster: Parallel Stacks

Für native und für managed CodeDie Fenster können geöffnet werden, wenn ein Breakpoint angelaufen wurdeDebug > Windows > Parallel TasksDebug > Windows > Parallel Stacks

Page 85: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Debugging

Parallel Tasks-Fenster:Unterstützung des Task-basierten ProgrammierensAuflistung aller Tasks

Waiting, Running, Scheduled,…

Ausgaben können konfiguriert und gruppiert werden

Page 86: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Debugging

Parallel Stacks-Fenster:In modernen Anwendungen laufen oft mehrere Threads gleichzeitigDas Fenster zeigt die hierarchische Aufrufreihenfolge von Threads an

…siehe Call-Stack (ohne Threading-Info‘s)

Ausgaben können in unterschiedlicher Weise dargestellt werden

TopDown, BottomUp, Zooming, Panning,…

Page 87: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Visual Studio: TestDebug

demo

Page 88: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Debugging

Suche nach Deadlocks ist mit dem VS-Debugger möglichBenutzung des Parallel-Tasks-Fensters

Page 89: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Visual Studio: TestDead

demo

Page 90: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Debugging

Ausgaben werden meistens mit Console.WriteLine(…) gemachtProblem: Console.WriteLine(…) blockiert alle Threads, damit die Ausgabe auch lesbar sindDadurch wird natürlich das „laufende“ Threading stark beeinflusst und es können nicht erwünschte Zustände entstehenLösung: Console-Ausgabe entkoppeln

Page 91: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

ConsoleEx

demo

Page 92: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

DataBinding mit ThreadingEigentlich sollte DataBinding mit MultiThreading Schwierigkeiten machenD.h., die Business-Logik läuft in einem anderen Thread, als das User InterfaceDas ist auch so – bis einschließlich .NET Framework 2.0

Siehe Beispiel

Page 93: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

WPF-DataBinding mit ThreadingBei WPF hat Microsoft etwas weiter gedacht… Vor der Ausführung des Bindings wird geprüft, ob der richtige Thread benutzt wird

Wenn nicht, wird mit Dispatcher.Invoke umgeschaltet

DataBinding mit WPF und MultiThreading ist also kein großes Problem…ab einschl. .NET Framework 3.0Funktioniert nicht bei Windows Forms!

Page 94: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Test_Binding_WPF

demo

Page 95: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Zusammenfassung

Es gibt neue Möglichkeiten, um Code zu parallelisierenWir müssen keine Threads mehr explizit erzeugenSchleifen sind einfach zu parallelsierenCode ist besser zu lesen, als mit einzelnen ThreadsAuch Codeblöcke kann man einfach paralellisieren

Page 96: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

Zusammenfassung

Trotzdem gibt es Fälle, bei denen eine Parallelisierung nichts bringt

Testen, Prototyp erstellenGgf. seriellen Code verwenden

Die Klassen Task und Task<T> ermöglichen die präzisere Steuerung des parallelen CodesParallel Linq bietet einfachere Möglichkeiten der parallelen Programmierung, als die bisherige Anwendung von normalen Threads

Page 97: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

WeitereInfo‘s

Page 99: Parallelprogrammierung mit der TPL und.NET 4.0 Bernd Marquardt – bm@go-sky.de

FRAGEN?