Suchergebnis

Workshops und Tutorials für Parallelprogrammierer

veröffentlicht von Michael Hülskötter am 06. Mai 2009 (0) Kommentare

Was mir als Software-Dev-Blogger wirklich am Herzen liegt, ist ein möglichst hoher Nutzwert, den meine Blog-Beiträge bieten sollen. Daher haben sich im Laufe der letzten gut sechs Monate einige Workshops und Tutorials angesammelt, die zeigen, wie die parallele Programmierung vonstattengeht. Und damit diese Tipps und Tricks nicht in Vergessenheit geraten, folgt jetzt die ultimative Tutorial-Sammelliste:

>> Los ging es mit den bekannten Multithreading-Konzepten OpenMP, APIs und Intel Threading Building Blocks und der Frage, welche der drei Methoden sich zum Threaden am besten eignet.

>> Dann folgten fünf Multicore-Programmierregeln, die zeigen sollen, mit welchen Anforderungen Programmierer und Software-Entwickler konfrontiert werden, wenn sie sequenziellen Code in parallele Anwendungen überführen wollen. Ich sage nur: Denke parallel!

>> Ein wichtiges, weil fundamentales Konzept der Multicore-Programmierung ist der Unterschied zwischen Daten- und Aufgabenparallelität. Diesen zu verstehen ist die erste Programmiererpflicht, wenn es darum geht, skalierbare Multithread-Anwendungen zu erstellen.

>> Wie viele Schritte muss man gehen, um aus seriellem Quellcode parallel ablaufenden zu machen? Genau vier. Rein abstrakt betrachtet zumindest. Auch hierfür habe ich den passenden Workshop parat, der die vier Stufen der Parallelprogrammierung genauer beleuchtet.

>> Was aber, wenn ich zwar weiß, wie ich parallel programmieren soll, ich aber keinen Schimmer davon habe, welche Stolperfallen dabei auf mich warten? Da heißt es dann meinen Beitrag lesen, welche Fehler bei der Parallelprogrammierung der Entwicklergemeinde drohen und wie sich diese (die Fehler, nicht die Entwickler) umgehen lassen.

weiterlesen…

Categories : Multicore Tags : , ,

prio.powerday: Einführung in die parallele Programmierung

veröffentlicht von Michael Hülskötter am 23. April 2009 (0) Kommentare

Jetzt sind mit kaum einer halben Stunde Verspätung Ralf Westphal und Bernd Marquardt dran. Sie wollen uns erst mal erzählen, was parallele Programmierung eigentlich bedeutet.

Zunächst geht es um echte Basics wie Multithreading mit Single- und Multicores. Fakt ist: Multithreading allein bringt gar nichts, dafür sind mehrere Prozessoren und die Zerlegung eines Programms in parallel zu verarbeitenden Bereiche notwendig.

Eine weitere Herausforderung sind Latenzzeiten, die sich aus asynchroner Prozessorverarbeitung ergeben. Das lässt sich mithilfe einer Kombination aus Multithreading und Multitasking auf mehreren Prozessoren optimieren.

Es gilt aber zugleich, den Durchsatz zu erhöhen. Dies gelingt ausschließlich auf Multicore-Systemen.

Es gibt ein grundsätzliches Problem bei der Parallelverarbeitung: den Zugriff auf gemeinsame Ressourcen. Diese Herausforderung meistern Zugriffskontrollen mithilfe explizierter Sperren. Hierfür sperren zum Beispiel einzelne Tasks gemeinsamen Speicher. Allerdings müssen die Zeitspannen und die Granularität dieser Sperren genau passen. Ein große Gefahr hierbei sind übrigens mögliche Deadlocks, die gerade bei parallel programmierten Anwendungen erst zur Laufzeit auftreten. Deadlocks lassen sich durch dieselbe Sperrreihenfolge vermeiden.

weiterlesen…

Categories : Multicore Tags : , ,

prio.powerday: Multicore-Programmierung unter .NET

veröffentlicht von Michael Hülskötter am 23. April 2009 (0) Kommentare

Kaum dass ich aus Salzburg zurück bin, sitze ich hier im Konferenzhaus in der Lazarettstraße, München, und nehme an der Multicore-Konferenz für .NET-Entwickler teil, die im Rahmen der prio.powerdays stattfindet.

Den Anfang macht Rami Radi von Intel, der die Einführungsrede hält und die Anwesenden auf das Thema Multicore einstimmen will.

Rami beginnt seinen Vortrag mit Hardware, nicht mehr Software. Namentlich spricht er über den Core i7-Prozessor, der ja im höchsten Maße multithreading-tauglich ist. Core i7 verarbeitet nämlich pro Prozessorkern zwei Threads simultan.

Die nächste Folie zeigt die ganze Vielfalt der Intel-Entwicklertools, über die ich hier schon ausführlich berichtet habe, also über Compiler, VTune etc.

So, jetzt wird’s ernst. Rami spricht über die Parallelprogrammierung im .NET-Umfeld, was seiner Meinung nach nicht einfach ist (wären wir sonst hier?). Zu den Herausforderungen gehören unter anderem falsch genutzter Speicher, zu viele und zu wenige Threads, gemeinsam genutzte Speicherbereiche, Load Balancing und viele andere. Wie gut, dass es für diese “Issues” die passenden Tools gibt wie den VTune Performance Analyzer.

weiterlesen…

Categories : Multicore Tags : , ,

Workshop: Alles über .NET-Threads – Teil 4

veröffentlicht von Michael Hülskötter am 16. März 2009 (0) Kommentare

Eine neue Woche beginnt, und im selben Atemzug endet meine vierteilige Serie zum Thema .NET-Threads. So habe ich im ersten Kapitel über das Erzeugen von Threads geschrieben, im zweiten Teil mich über das Verwalten derselben ausgelassen, und am letzten Donnerstag war der ThreadPool und dessen Möglichkeiten dran. Und heute?! Nun, heute geht es um die Synchronisierung mehrerer Threads und atomare Aktionen.

Zunächst einmal kann man festhalten, dass die Thread-Synchronisierung im .NET-Framework ähnlich funktioniert wie im Win32- oder Pthreads-Umfeld. Es geht also um den gegenseitigen Ausschluss sowie um atomare Aktionen auf spezielle Variablen. Wie bei der von C# bekannten Methode lock wird ein Codeabschnitt mithilfe der geschweiften Klammern geblockt, sodass zu dieser Zeit nur ein einziger Thread darauf zugreifen kann. Hierfür bietet das .NET-Framework eine ähnliche Konstrukte:

Monitor.Enter ( this )
try
{
……. shared_var = other_shared_var +1;
……. other_shared_var = 0;
}
finally
{
…… Monitor.Exit ( this )
}

Mit der Klasse Monitor wird der entsprechende Codeabschnitt blockiert. Mit Enter() wird der Abschnitt gesperrt und mit Exit() wieder freigegeben. Praktisch an Monitor ist auch dessen Möglichkeit, Datenstrukturen als Parameter zu übergeben.

Bei Monitor.Enter() geschehen übrigens zwei Dinge: Erstens wird eine Warteschlange eingerichtet, die auf diejenigen Threads verweist, die gesperrt werden sollen und eine zweite Queue mit Threads, die darüber informiert werden wollen, wenn eine Speere verfügbar ist. Monitor.Exit() sorgt dafür, dass der erste verfügbare Thread in Warteschlange #1 gesperrt wird.

weiterlesen…

Categories : Multicore Tags : , ,

Workshop: Alles über .NET-Threads – Teil 3

veröffentlicht von Michael Hülskötter am 12. März 2009 (2) Kommentare

Teil eins und Teil zwei meines Minispecials zum Thema .NET-Threads stehen bereits online, und heute folgt sehr chronologisch der dritte Abschnitt. Dieser handelt von den Thread-Pools, mit deren Hilfe eine größere Anzahl von notwendigen Threads mithilfe des .NET-Frameworks verwaltet werden können.

Zunächst einmal sollte man sich klar machen, dass das Erzeugen und Verwalten von .NET-Threads mit einem immensen administrativen Aufwand verbunden ist: Lokaler Thread-Speicher muss angelegt und die Systemstrukturen für die Thread-Verwaltung müssen eingerichtet werden. Darüber hinaus nimmt die Komplexität des Quellcodes deutlich zu, sobald mehrere Threads mit Bordmitteln verwaltet werden sollen.

Aus diesem Grund hat Microsoft dem .NET-Framework ein Ressource spendiert, die sich ThreadPool nennt. Dabei wird zunächst eine bestimmte Anzahl von Threads generiert, außerdem wird eine Art Arbeitswarteschlange erstellt. Sobald eine auszuführende Aufgabe in diese Warteschlange befördert wird, wird ein Thread für diesen Task aktiviert und ihm die Aufgabe zugewiesen. Dies erledigt das .NET-Framework automatisch. Allerdings ist dabei zu beachten, dass der ThreadPool nur dann sinnvoll eingesetzt werden kann, wenn ein Programm aus mehreren Threads besteht, die immer wieder benötigt werden.

weiterlesen…

Categories : Multicore Tags : , ,

Workshop: Alles über .NET-Threads – Teil 2

veröffentlicht von Michael Hülskötter am 11. März 2009 (0) Kommentare

Meine kleine .NET-Serie zum Thema Threads geht heute in die zweite Runde. Nachdem es gestern um das Erzeugen von Threads ging, handelt Teil zwei von der Thread-Verwaltung. Dabei unterscheidet man zwischen Beenden, Warten, Anhalten und Fortsetzen.

Beenden von Threads: Dies geschieht am einfachsten, indem ein Thread ganz regulär während des Programmablaufs verlassen wird und die Anwendung wieder zum Masterthread zurückkehrt. Dies gibt der Common Language Runtime (CLR) die Möglichkeit, die notwendigen Aufräumarbeiten durchzuführen. Allerdings muss manchmal ein anderer als der gerade laufende Thread beendet werden. Daher hat Microsoft den .NET-Thread-APIs eine Methode spendiert, die sich Abort() nennt, mit deren Hilfe ein laufender Thread abgebrochen werden kann. Beim Aufruf von Abort() wird automatisch eine ThreadAbortException ausgelöst.

Der Aufruf von Abort() zieht übrigens eine Reihe verschiedener Dinge nach sich. Dazu gehört die Fähigkeit des Threads, den eigenen Abbruch zu vereiteln, indem er innerhalb des Exception-Handlers die Methode System.Threading.Thread.ResetAbort aufruft. Daneben besteht die Möglichkeit, innerhalb eines Codeblocks mithilfe von finally weiteren Quellcode ausführen zu lassen, was im ungünstigsten Fall eine beachtliche Verzögerung des Thread-Abbruchs nach sich zieht. Aus diesen beiden Gründen sollte man zur Laufzeit überprüfen, ob ein bestimmter Thread auch vollständig abgebrochen wurde. Hierfür steht die Join-Methode zur Verfügung.

weiterlesen…

Categories : Multicore Tags : , ,

Workshop: Alles über .NET-Threads – Teil 1

veröffentlicht von Michael Hülskötter am 10. März 2009 (0) Kommentare

Ende Januar, im Anschluss an die OOP 2009, habe ich hier eine kleine Miniserie mit dem Titel “Multicore-Programmierung im .NET-Umfeld” veröffentlicht. Was dabei ein wenig zu kurz kam sind die technischen Aspekte, die daraus resultieren. Wie beispielsweise Threads mithilfe des .NET-Frameworks erzeugt, verwaltet und synchronisiert werden. Und über die vorhandenen Thread-Pools habe ich ebenfalls zu wenig erzählt.

Das alles werde ich ab heute in Form einer Miniserie mit der Überschrift “Alles über .NET Threads” nachholen. Der erste Teil beschäftigt sich mit dem Thema “Threads erzeugen”.

Da die .NET-APIs etwas “schlanker” sind als ihre Win32-Brüder und -Schwestern, gestaltet sich das Erzeugen eines .NET-Threads relativ einfach. Dies sieht wie folgt aus:

using System.Threading;

[Definition von Variablen]

Thread t = new Thread( new ThreadStart( ThreadFunc ));

Der Aufruf von ThreadStart() erzeugt einen neuen Thread. Der Parameter ist eine Delegat namens ThreadFunc. Übrigens: In C# ist ein Delegat identisch mit der Adresse einer Funktion in C. Der Thread endet dann an der Stelle, sobald ThreadFunc() endet. Doch damit nicht genug. Für eine fehlerfreie Ausführung des Threads muss weiterer Code implementiert werden:

t.Start() — Dies startet den Thread unter .NET explizit (was z. B. unter Win32 nicht erforderlich ist).

Thread.Sleep( 40 ) — Dies unterbricht den (seriellen) Hauptthread für die Dauer der Zeiteinheit in der Klammer, die in Millisekunden angegeben wird. Dies kann in der Praxis jedoch erheblich von der tatsächlich benötigten Zeit abweichen.

[aufzurufende Funktion] — Diese Funktion wird parallel auf den vorhandenen Prozessorkernen ausgeführt.

Thread.Sleep( 0 ) Dies beendet den parallelen Thread und reaktiviert den “schlafenden” Hauptthread.

Categories : Multicore Tags : , ,