en / de
Expertisen
Methoden
Dienstleistungen
Referenzen
Jobs & Karriere
Firma
Technologie-Trends TechCast WebCast TechBlog News Events Academy

C# Concurrency Teil 1: CPU-bound und IO-bound Tasks

Dies ist der erste Blog aus einer ausführlichen Serie zu C# Concurrency.
Für viele Programmierer ist parallele Programmierung eine Grauzone. Durch die syntaktische ‚Vereinfachung‘ mit den async\await Schlüsselwörtern im Framework 4.5 ist die Komplexität einmal mehr kaschiert und die Gefahr für versteckte Fehler gestiegen.
Diese Serie sensibilisiert den Programmierer auf diese Gefahren und erklärt Schritt für Schritt die Aspekte der modernen parallelen Programmierung.

Zu Beginn sollen die 2 Arten von Aufgaben eingeführt werden: CPU-bound– und IO-bound-Aufgaben. Aufgabe und Tasks werden hier synonym verwendet.

CPU-bound Task

Ein CPU-bound Task repräsentiert eine rechenintensive Aufgabe die nicht abhängig ist von externen Resourcen; sie beansprucht pure Prozessorleistung. CPU-bound Tasks sind deshalb geeignet für parallele Verarbeitung auf mehreren Prozessoren (Multiprocessing) weil so Verarbeitungsdauer reduziert werden kann.

CPU-bound Aufgaben wurden am Anfang der .NET Ära durch das Erzeugen von Threads gemacht, später wurde dies vereinfacht durch den Thread-Pool. Heute werden diese Aufgaben mit der Task Parallel Library (TPL) und mit speziellen Klassen für parallele Datenverarbeitung gelöst (z.B. parallel LINQ und Typ Parallel). Die bewerte Thread Klasse ist aber in spezielle Situationen immer noch die einzige Lösung.

Ein viel gemachter Fehler ist das Lösen von CPU-bound Aufgaben mit async\await. Dadurch wird die Verarbeitung weder schneller noch benötigt sie weniger Resourcen.

IO-bound Task

Ein IO-bound Task ist abhängig von externen Resourcen wie Netzwerk, Datenbank oder IO-System. IO-bound Tasks sind asynchrone Tasks. In der Regel wird eine Abfrage an die Resource gesendet und auf die Antwort gewartet. Während des Wartens auf die Antwort, kann der Thread verwendet werden für andere Aufgaben. Die Applikation braucht dadurch weniger Ram und Prozessorzyklen.

Eine IO-bound Aufgabe wird in einem modernen .NET Programm mit async\await gelöst. Die TPL Klassen sind ungeeignet, weil damit ein Thread belegt wird während des Wartens und dadurch unnötig Ressourcen gebunden werden.

Beispiel aus der echten Welt

Eine kleine Firma schneidet und verpackt Salat.

Manuell eine Person

erik stroeken multithreading cooperative multitasking
CPU-bound Task: Multithreading mit Cooperative Multitasking

Eine Person schneidet und verpackt den Salat manuell.
Ohne Maschinen ist diese Arbeit intensiv und beansprucht die Resource ‚Person‘ vollständig. Dies ist ein CPU-bound Task. Weil es nur eine Resource gibt (die Person), müssen die Aufgaben (Schneiden und Verpacken) verteilt werden über eine Resource (Multithreading). Weil die Person selber entscheidet wann er zwischen den Aufgaben wechselt, ist dies Cooperative Multitasking.
Dabei kann er erst das Schneiden komplett erledigen und danach das Verpacken.
Er kann aber auch abwechseln zwischen den Aufgaben. Das Wechseln (Context Switch) kostet  Zeit wodurch die Gesamtzeit zunimmt. Die grauen Flächen bei den Übergängen repräsentiert diese zusätzliche Zeit.

Manuell zwei Personen

erik stroeken concurrency cpu-bound task multiprozessing

CPU-bound Task: Multiprozessing

Weil sich die Arbeit aufteilen lässt auf mehreren Ressourcen, können die Arbeiten parallelisiert werden. Die Gesamtzeit ist beim gleichen Output dadurch kürzer. Weil das Verpacken schneller geht als das Schneiden, ist Person2 nicht voll ausgelastet. Die ‚Idle‘-Zeit kann für andere Aufgaben benutzt werden. Die Aufgabe Schneiden kann ebenfalls auf zwei Resourcen verteilt werden.

Dies wäre ein typischer Einsatzzweck für die Task Parallel Library (TPL). Durch Nutzung mehrerer Prozessoren wird die benötigte Zeit reduziert.

Automatisch, eine Person, 2 externe Ressourcen

concurrency io-bound task
IO-bound Tasks: die Ressource ,Person’ ist oft ‚Idle‘

Es geht gut mit der Firma und die Person beschliesst eine Schneide- und Verpackungsmaschine zu kaufen. Die Person muss nur noch die Maschinen ein- und ausräumen. Die Maschinen sind externe Resourcen die sich melden, wenn sie fertig sind oder einen Fehler aufgetreten ist. Man spricht von echten asynchronen Tasks oder IO-bound Tasks.

Automatisch, eine Person, N externe Ressourcen

concurrency io-bound -task
Skalierbarkeit dank IO-bound Tasks

Weil die Person jetzt meistens nur am Warten ist, kann sie mehrere Maschinen gleichzeitig bedienen. Bei gleicher Zeit nimmt jetzt der Output zu: skalierbar.

Mit async\await wird einen IO-bound Task (asynchrone Task) so abgearbeitet, dass der Thread für andere Aufgaben eingesetzt werden kann während des Wartens auf eine Antwort der externen Ressource. Das Ziel ist Skalierbarkeit.

Fazit

CPU-bound Tasks repräsentieren rechenintensive Aufgaben die mit Threads parallelisiert werden können. Ziel: Reduktion der Gesamtzeit.

IO-bound Tasks sind asynchrone Aufgaben und sind abhängig von externen Resourcen wie Netzwerk, Datenbank oder IO-System. Während des Wartens kann der Thread freigegeben werden für andere Aufgaben. Das wird Stand heutiger Technologie mit async\await gemacht. Ziel: Skalierbarkeit der Applikation.

Nächster Post →

Kommentare

2 Antworten zu “C# Concurrency Teil 1: CPU-bound und IO-bound Tasks”

  1. […] Letztes Mal haben wir den Unterschied angeschaut zwischen CPU-bound und IO-bound-Aufgaben um die richtigen Technologien wählen zu können. Siehe C# Concurrency Teil 1: CPU-bound und IO-bound Tasks […]

  2. […] die Blogserie ‘C# Concurrency’ die hier […]

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Newsletter - aktuelle Angebote, exklusive Tipps und spannende Neuigkeiten

 Jetzt anmelden
NACH OBEN
Zur Webcast Übersicht