Surf-Tipp: Parallel-Studio-Artikel kostenlos downloaden

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

Der werte Kollege Preiss von Intel war mal wieder fleißig und hat zur Parallelisierungssuite Parallel Studio einen kleinen, aber feinen Artikel erstellt. Und zwar für das Fachmagazin Elektronik Industrie, das den Beitrag kostenlos zum Download anbietet.

Für aufmerksame Leser des Software Dev Blogs werden sich nicht sonderlich viele Neuigkeiten aus dem Beitrag ableiten lassen, aber in seiner Abgeschlossenheit trägt der Artikel doch sehr zum Verständnis von Parallel Studio bei. Zudem handelt es sich um ein PDF-Dokument, das sich sogar ausdrucken lässt. Für die analogen Zeitgenossen unter uns.

Der Artikel umfasst drei Seiten und geht recht detailliert auf die einzelnen Komponenten ein, also Parallel Composer, Parallel Inspector und Parallel Amplifier. Lustigerweise beginnt der Beitrag mit dem Parallel Advisor. Dieses Tool wird erst in der nächsten Version zum Parallel Studio gehören, kann allerdings heute schon als eine Art Techdemo kostenlos ausprobiert werden.

Schön an dem Parallel-Studio-Beitrag sind die praxisorientierten Einblicke, die man anhand der eingefügten Bilder gewinnen kann. Schade ist allerdings, dass diese teilweise recht klein geraten sind. Und ein, zwei Codebeispiele hätten dem Artikel zu ein wenig mehr Pfiff verholfen. Na ja, beim nächsten Mal dann, ok?!

Kategorien : 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…

Kategorien : 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…

Kategorien : 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…

Kategorien : 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.

Kategorien : Multicore Tags : , ,

Infos rund ums Parallele Programmieren auf MSDN

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

Heute Morgen habe ich nicht schlecht gestaunt, als mich Google Alert darüber informiert hat, dass es eine externe Verlinkung zu einem meiner Blogbeiträge gibt. Dabei handelt es sich um einen Workshop, der sich mit den Methoden der parallelen Programmierung mithilfe von OpenMP beschäftigt.

Besonders bemerkenswert daran fand ich übrigens die Seite, die den Beitrag verlinkt hat: Es handelt sich um niemand geringeres als MSDN, also das Entwicklerportal von Microsoft, die dem Thema Parallele Programmierung eine eigene Webseite spendiert haben. Und genau dort findet man den Link auf meinen OpenMP-Beitrag. Daneben gibt es noch weitere interessante Einstiege in die Welt der Multithreading-Entwicklung. Da erfährt man eine Menge über die Grundlagen der Parallelprogrammierung, aber auch Tools und Downloads werden dort vorgestellt.

Des Weiteren können interessierte Entwickler nützliche Artikel abgreifen, Webcasts und Videos angucken und Blogs lesen. Und klar, dass es auf der Webseite auch um die Themen Paralleles Programmieren mit .NET geht. Besonders bemerkenswert finde ich auch die Tatsache, dass MSDN für Intel eine eigene Sektion mit Namen “Intel Developer Network” spendiert hat. Dort findet man Wissenswertes zum Parallel Studio und zu anderen Themen.

Fazit: Parallel Computing auf MSDN ist eine bookmark-taugliche Webseite, wenn man in Sachen Parallele Programmierung auf dem Laufenden bleiben will.

Kategorien : Multicore Tags : , , ,

Mögliche Thread-Modi und deren Folgen

veröffentlicht von Michael Hülskötter am 27. Februar 2009 (1) Kommentar

Multicore-Programmierung ist sicherlich kein einfaches Ding. Zu viel kann dabei passieren und schiefgehen, wenn man bestimmte Regeln nicht beachtet. Daher starten wir heute einen Mehrteiler, der sich mit den Details der Multicore-Programmierung beschäftigt. Im ersten Teil geht es um die fundamentale Frage, welche Zustände ein Thread während des Programmablaufs annehmen kann.

Im ersten Schritt wird beispielsweise vom Thread Manager ein Thread erzeugt und in den Bereit-Zustand versetzt (”ready”). Dort verharrt der Thread so lange, bis er eine Anweisung, eine Funktion oder ähnliches ausführen soll. Darum kümmern sich entsprechende Programmanweisungen wie zum Beispiel die Pragma-Methoden der OpenMP-basierten Programmierung.

Im zweiten Schritt kommt es zur Ausführung der entsprechenden Quellcodestelle. Währenddessen muss der betreffende Thread möglicherweise auf einen anderen Thread oder ein Datum eines parallel ablaufenden Threads warten. Dann begibt er sich in den Wartend-Modus, bis der benötigte Thread beendet ist oder dessen Ergebnis vorliegt. Anschließend wird der angehaltene Thread weiter ausgeführt oder wieder in den Bereit-Zustand versetzt, da der Thread zu einem späteren Zeitpunkt nochmals benötigt wird.

Ach ja: Gerade dieser Wartend-Modus bereitet vielen Programmierern erhebliche Probleme, da hierbei Dead Locks, Data Races oder andere unvorhersehbare Ereignisse auftreten können. Wie gut, dass es hierfür Tools wie den Thread Checker oder Parallel Inspector gibt, die solche Schwachstellen aufspüren können.

weiterlesen…

Kategorien : Mobile Tags : , ,

Multicore-Programmierung im .NET-Umfeld – Teil 3

veröffentlicht von Michael Hülskötter am 2. Februar 2009 (2) Kommentare

Nach den Teilen eins und zwei folgt heute der dritte Abschnitt unserer Mini-Serie “Multicore-Programmierung im .NET-Umfeld”. Es geht um Tasks und Futures, um das Parallelisieren von Methoden, um parallele Schleifen, um einen Taskmanager und um PLINQ.

Tasks sind die zentralen Elemente der Parallel Extensions, also dedizierte Aufgaben, Funktionen, Schleifenkonstrukte oder ähnliche Dinge. Eine Task führt stets eine Funktion oder ein anderes Konstrukt innerhalb eines Threads aus, um so eine optimale Ausnutzung der Systemressourcen zu erzielen.

Das Besondere daran sind die Call-Back-Funktionen, die es ermöglichen, bestimmte Dinge zu übergeben, die in einem separaten Thread ausgeführt werden sollen. Mithilfe der Tasks müssen Anwendungsprogrammierer also nicht mehr in Threads denken, da diese von den .NET-Tools automatisch erzeugt, verwaltet und auf die vorhandenen Ressourcen verteilt werden.

Daneben gibt es Futures, also Tasks mit Rückgabewerten. Solch ein Future-Konstrukt führt beispielsweise in einem eigenen Task eine Funktion aus, deren Ergebnis an das Hauptprogramm übergeben wird, das währenddessen weiterrechnen kann. Zwar muss das Programm an einer bestimmten Stelle auf das Ergebnis warten, kann aber trotzdem parallel andere Aufgaben ausführen. Eine weitere simultane Ausführungsoption ist die Methode Parallel_Invoke(), die einen ganzen Satz von Methoden zugleich abarbeiten kann, sofern diese voneinander unabhängig sind.

weiterlesen…

Kategorien : Multicore Tags : , ,

Multicore-Programmierung im .NET-Umfeld – Teil 2

veröffentlicht von Michael Hülskötter am 30. Januar 2009 (2) Kommentare

Wie ich gestern versprochen habe, folgt heute der zweite Teil meines Mini-OOP-Specials zum Thema Multicore-Programmierung in der .NET-Welt.

Im einleitenden Teil habt ihr unter anderem erfahren …

… warum es mittlerweile mehr Anstrengungen erfordert, bestehende oder neue Anwendungen auf vorhandenen Computerplattformen schneller zu machen,

… was die Gesetze von Amdahl und Gustafson für die parallele Programmierung bedeuten

… und auf welchen Elementen moderne Programmarchitekturen basieren.

Im heutigen zweiten Teil geht es ans Eingemachte: Welche Hürden sind bei der Multicore-Programmierung im .NET-Umfeld zu überwinden? Welche Tools gibt es bereits dafür? Und was kommt auf die Entwickler in den nächsten Monaten noch alles zu?

Die gute Nachricht: Multithreading wird mittlerweile von den nativen Programmiersprachen wie C++ und Fortran bestens unterstützt. Hierfür gibt es auch diverse Tools wie Threading Building Blocks, Thread Checker und OpenMP, die Entwickler für die Parallelprogrammierung einsetzen können. In Sachen C#, Java und Python sieht es zwar (noch) nicht ganz so gut aus, aber es gibt bereits einige Methoden, Multithreading in .NET-Applikationen zu realisieren. Dabei handelt es sich um Konstrukte zum Erzeugen und Synchronisieren von Threads, aber auch zum Sperren von gemeinsamen Ressourcen (Speicher) und zum Verwalten von Threadpools.

weiterlesen…

Kategorien : Multicore Tags : , ,

Multicore-Programmierung im .NET-Umfeld – Teil 1

veröffentlicht von Michael Hülskötter am 29. Januar 2009 (3) Kommentare

Gestern war ich auf der zweiten Multicore-Session der OOP 2009 (am Dienstag wohnte ich dem Vortrag von Professor Tichy der Uni Karlsruhe bei). Die Mittwoch-Veranstaltung trug den Titel “Programmierung für Multicore-CPUs”, die sich im Speziellen an .NET-Entwickler richtete. Warum Klaus Bode nicht auf native Programmiersprachen wie C++ eingegangen ist, erklärte er mir im Anschluss an seinen Vortrag; das ist aber eine andere Geschichte.

Die Session gliederte sich in vier Abschnitte: Einleitung, Parallelisierung durch Multithreading, neue Konzepte in .NET 4.0 und Ausblick. Die Zusammenfassung verschweige ich einfach mal.

Der erste Teil “Einleitung” beschäftigte sich vor allem mit der Frage, warum das kostenlose Mittagessen vorbei ist. Dies ist die zugegebenermaßen schwachsinnige Übersetzung eines englischsprachigen Artikels, der sich mit der Tatsache beschäftigt, dass Prozessoren seit Jahren nicht mehr schneller werden (sondern eher langsamer) und man daher als Entwickler keine Geschwindigkeitszuwächse mehr erwarten kann, die quasi kostenlos für mehr Leistung sorgen, ohne dass man hierfür am Quellcode herumschrauben muss. Das heißt dann im Umkehrschluss, dass sich Programmierer in Zukunft intensiv mit dem Thema Parallelprogrammierung auseinandersetzen müssen, um aus den künftigen Multicore-Prozessoren das Optimum herauszuholen.

Um die möglichen Schwierigkeiten der Parallelprogrammierung zu verdeutlichen, wies Rohe zunächst auf die Architektur des Core 2 Duo Prozessors von Intel hin, der aus zwei Kernen mit einem eigenem L1-Cache besteht, aber zudem über einen gemeinsamen L2-Cache verfügt. Und genau das stellt eine der wesentlichen Herausforderungen der Parallelprogrammierung dar: der gemeinsame Speicherzugriff mit all seinen unvorhersehbaren Verklemmungen und Problemen!

weiterlesen…

Kategorien : Multicore Tags : , ,