Teil 5: Erkennen von Flaschenhälsen und Problemen

.Net-Anwendungen für Multi-Core optimieren

Optimierung von Multithreaded .NET-Applikationen

Nach all den vorangegangenen Erläuterungen zur Aufteilung des Codes in mehrere Threads und deren Synchronisation bleibt schließlich die Frage, was das das optimale Vorgehen dabei ist. Sicherlich kann dies nicht in einer Flut an Threads liegen, die dann dem ThreadPool übergeben werden. Außerdem wird der Code nicht alleine dadurch effizienter, wenn er wahllos in mehrere Threads zerlegt wird, die dann mehr oder weniger parallel laufen.

Für den Entwickler bleibt daher die Anforderung, einen gut abgestimmten und auch optimierten Source-Code zu erstellen. Dabei gilt es, all jene Code-Passagen ausfindig zu machen, die sich für eine parallele und asynchrone Verarbeitung am besten eignen und folglich auf separate CPU-Cores ausgelagert werden können.

Gleichzeitig sollen aber auch nicht übermäßig viele Threads erzeugt werden. Denn Threads benötigen CPU-Laufzeiten und die Verwaltung durch das Betriebssystem. Um eine optimale Thread-Aufteilung zu erreichen, kommt daher der Fehlersuche und Performanzanalyse eine entscheidende Rolle zu.

Wie viele Threads?

Die Suche nach der richtigen Anzahl von Threads ist keine einfache Aufgabe. So sollen sicherlich nicht mehr Threads erzeugt werden, als das System auch vernünftig verwalten kann. Ein theoretischer Ansatz zur Ermittlung der richtigen Anzahl ist der folgende:

NumThreads = NumCPUs / (1 – BP)

BP steht dabei für den prozentualen Zeitanteil, in dem Tasks geblockt sind. Laut dieser Formel soll die Anzahl der Threads gleich sein mit dem Verhältnis der CPUs zum Anteil der Tasks, die tatsächlich parallel ausgeführt werden. Wenngleich das nur ein theoretischer Wert ist, so mag es als Annäherung dennoch hilfreich sein.