prio.powerday: Parallele Programmierung unter .NET 3.5

veröffentlicht von Michael Hülskötter am 23. April 2009

Nach der Mittagspause ist Bernd Marquardt ohne sein Alter Ego an der Reihe. Sein Thema: Parallele Programmierung mithilfe des .NET-Frameworks 3.5, und zwar per TPL.

Folgende Elemente kommen zum Einsatz:

  • Schleifen parallelisieren: Die hierzu gehörige Klasse heißt System.Threading.Parallel. Schleifen werden auf mehrere Threads aufgeteilt werden, aber nur, wenn die einzelnen Schleifendurchläufe unabhängig voneinander sind. Dabei müssem die Indezies alle gleich sein. Am Ende der Schleife werden alle Threads synchronisiert. Fazit: Schleifenparallelisierung lohnt sich nur bei komplexen und großen Schleifen! Wichtig ist auch die richtige Verteilung einer Schleife auf die vorhandenen Prozessorressourcen. Dies gelingt, indem die einzelnen Schleifendurchläufe in kleinen Portionen verarbeitet werden.
  • Aggregationen: Hierbei geht es um das Zusammenfassen von Ergebnissen. Dabei ist Locking meist erforderlich. Zwischenwerte werden über sogenannte ThreadLocateState weitergegeben. Der Ablauf sieht folgendes vor: Initialisierung, Zwischenspeichern der einzelnen Thread-Ergenisse und das abschließende Zusammenführen der Zwischenwerte inklusive Locking. Übrigens: Aufgrund des Zusammeführens der einzelnen Thread-Zwischenergebnisse kann ist bei der parallelen Ausführung zu Rundungsfehlern kommen und das Ergebnis weicht vom sequentiellen Programm ab.

  • Codeblöcke parallelisieren: Hier kommt die Invoke-Methode zum Einsatz.
    • Die Task-Klasse: Diese funktioniert ähnlich wie die ThreadPool-Klasse und haben dieser gegenüber wesentliche Vorteile: Sie lassen sich mit wait() synchronisieren und abbrechen. Interessant an dieser Task-Klasse ist die Tatsache, dass dahinter ein spezieller Thread-Pool steckt, der deutlich schneller als der Standard-Threadpool arbeitet.
    • Die Future-Klasse: Sie ist abgeleitet von der Task-Klasse und ermöglicht die asynchrone Berechnung von Daten. Dabei wird auf Daten, die noch berechnet werden, automatisch gewartet oder das Endergebnis sofort ausgegeben. Die Future-Klasse eignet sich übrigens dazu, die Bedienoberfläche von Hintergrundberechnungen zu entkoppeln und damit die Anwendungen performanter zu machen.
    • Concurrent Exceptions: Im Gegensatz zu sequentiellen Anwendungen können in parallelisierten Applikationen zu einer bestimmten Zeit mehrere Exceptions ausgeworfen werden. Hierfür ist natürlich ein anderer Exception-Mechanismus erforderlich. So müssen zum Beispiel im Falle einer Exception mehrere Threads gleichzeitig angehalten werden.
    • Synchronisierung: Hierfür sind diverse Klassen im .NET-Framework vorhanden wie Lazyinit und WriteOnce.

    Tipps und Tricks:

    • Bei Parallel.For und Parallel.ForEach muss die (Anzahl der Durchläufe * Dauer) auf jeden Fall groß genug sein (beispielsweise schlägt bei der Matrix-Multiplikation die Parallelisierung erst bei sehr großen Matrizen voll durch).
    • Nur äußere Schleifen parallelisieren wegen der Abhängigkeiten der Variablen
    • Amdahl’s Gesetz berücksichtigen

    Share/Bookmark
    Kategorien : Multicore Tags : , , ,

    Kommentare

    Keine Kommentare vorhanden.


    Beitrag kommentieren.

    Sie müssen angemeldet sein um diesen Beitrag zu kommentieren. [Login | Registrieren]

    (erforderlich)

    (erforderlich)