Was bedeuten die Begriffe "CPU gebunden" und "I/O gebunden"?
Antworten
Zu viele Anzeigen?Wenn Ihr Programm wartet auf E/A (z. B. Lesen/Schreiben auf der Festplatte oder Lesen/Schreiben im Netzwerk usw.), kann die CPU andere Aufgaben erledigen, auch wenn Ihr Programm angehalten ist. Die Geschwindigkeit Ihres Programms hängt größtenteils davon ab, wie schnell die E/A erfolgen kann. Wenn Sie die Geschwindigkeit erhöhen wollen, müssen Sie die E/A beschleunigen.
Wenn Ihr Programm viele Programmanweisungen ausführt und nicht auf E/A wartet, wird es als CPU-gebunden bezeichnet. Wenn Sie die CPU beschleunigen, wird das Programm schneller laufen.
In beiden Fällen liegt der Schlüssel zur Beschleunigung des Programms möglicherweise nicht in der Beschleunigung der Hardware, sondern in der Optimierung des Programms, um die Menge an E/A oder CPU, die es benötigt, zu reduzieren, oder um es E/A ausführen zu lassen, während es auch CPU-intensive Aufgaben erledigt.
Lesen Sie, was Microsoft sagt.
Der Kern der asynchronen Programmierung sind die Objekte Task und Task, die asynchrone Operationen modellieren. Sie werden durch die Schlüsselwörter async und await Schlüsselwörter unterstützt. Das Modell ist in den meisten Fällen recht einfach:
Bei E/A-gebundenem Code warten Sie auf eine Operation, die eine Task oder Task innerhalb einer asynchronen Methode zurückgibt.
Bei CPU-gebundenem Code warten Sie auf eine Operation, die auf einer Hintergrund-Thread mit der Methode Task.Run gestartet wird.
Das Schlüsselwort await ist der Schlüssel zum Erfolg. Es übergibt die Kontrolle an den Aufrufer der Methode, die await ausgeführt hat, und ermöglicht letztlich eine UI reaktionsfähig oder ein Dienst elastisch zu sein.
E/A-gebundenes Beispiel: Herunterladen von Daten aus einem Webdienst
private readonly HttpClient _httpClient = new HttpClient();
downloadButton.Clicked += async (o, e) =>
{
// This line will yield control to the UI as the request
// from the web service is happening.
//
// The UI thread is now free to perform other work.
var stringData = await _httpClient.GetStringAsync(URL);
DoSomethingWithData(stringData);
};
CPU-gebundenes Beispiel: Ausführen einer Berechnung für ein Spiel
private DamageResult CalculateDamageDone()
{
// Code omitted:
//
// Does an expensive calculation and returns
// the result of that calculation.
}
calculateButton.Clicked += async (o, e) =>
{
// This line will yield control to the UI while CalculateDamageDone()
// performs its work. The UI thread is free to perform other work.
var damageResult = await Task.Run(() => CalculateDamageDone());
DisplayDamage(damageResult);
};
Die obigen Beispiele haben gezeigt, wie Sie async und await für E/A-gebundene und CPU-gebundene Arbeit verwenden können. Es ist wichtig, dass Sie erkennen können E/A- oder CPU-gebunden ist, denn dies kann die Leistung Ihres Codes die Leistung Ihres Codes stark beeinträchtigen und möglicherweise zu zur falschen Verwendung bestimmter Konstrukte führen kann.
Hier sind zwei Fragen, die Sie sich stellen sollten, bevor Sie einen Code schreiben:
Wird Ihr Code auf etwas "warten", z. B. auf Daten aus einer Datenbank?
- Wenn Ihre Antwort "ja" lautet, dann ist Ihre Arbeit I/O-gebunden.
Wird Ihr Code eine sehr teure Berechnung durchführen?
- Wenn Sie mit "Ja" geantwortet haben, dann ist Ihre Arbeit CPU-gebunden.
Wenn die Arbeit, die Sie haben, I/O-gebunden ist, verwenden Sie async und await sans Aufgabe.Ausführen . Sie sollten die Task Parallel Library nicht verwenden. Der Grund dafür wird im Abschnitt Async in der Tiefe Artikel.
Wenn die Arbeit, die Sie haben, CPU-gebunden ist und Sie Wert auf Reaktionsfähigkeit legen, verwenden Sie async und await, aber lassen Sie die Arbeit auf einem anderen Thread ablaufen mit Aufgabe.Ausführen. Wenn die Arbeit für Gleichzeitigkeit und Parallelität geeignet ist, sollten Sie auch die Verwendung der Aufgabe Parallele Bibliothek .
Die E/A-Beschränkung bezieht sich auf eine Bedingung, bei der die Zeit, die für den Abschluss einer Berechnung benötigt wird, hauptsächlich durch die Zeit bestimmt wird, die für das Warten auf den Abschluss von Eingabe-/Ausgabeoperationen benötigt wird.
Dies ist das Gegenteil davon, dass eine Aufgabe an die CPU gebunden ist. Dieser Umstand tritt ein, wenn die Rate, mit der Daten angefordert werden, langsamer ist als die Rate, mit der sie verbraucht werden, oder mit anderen Worten, es wird mehr Zeit mit der Anforderung von Daten verbracht als mit deren Verarbeitung.
Eine Anwendung ist CPU-gebunden, wenn die Rechen-/Logik-/Gleitkommaleistung (A/L/FP) während der Ausführung meist in der Nähe der theoretischen Spitzenleistung des Prozessors liegt (Angaben des Herstellers und bestimmt durch die Merkmale des Prozessors: Anzahl der Kerne, Frequenz, Register, ALUs, FPUs usw.).
Die Spitzenleistung ist in der Praxis nur sehr schwer zu erreichen, um nicht zu sagen unmöglich. Die meisten Anwendungen greifen in verschiedenen Teilen der Ausführung auf den Speicher zu, und der Prozessor führt während mehrerer Zyklen keine A/L/FP-Operationen durch. Dies wird als Von-Neumann-Beschränkung aufgrund der Entfernung zwischen dem Speicher und dem Prozessor.
Wenn Sie in der Nähe der CPU-Spitzenleistung sein wollen, könnte eine Strategie darin bestehen, zu versuchen, den Großteil der Daten im Cache-Speicher wiederzuverwenden, um zu vermeiden, dass Daten aus dem Hauptspeicher benötigt werden. Ein Algorithmus, der diese Eigenschaft ausnutzt, ist die Matrix-Matrix-Multiplikation (wenn beide Matrizen im Cache-Speicher gespeichert werden können). Dies geschieht, wenn die Matrizen die Größe n x n
dann müssen Sie etwa 2 n^3
Operationen, die nur 2 n^2
FP-Nummern von Daten. Andererseits ist z. B. die Matrixaddition eine weniger rechenintensive oder speicherintensive Anwendung als die Matrixmultiplikation, da sie nur n^2
FLOPs mit denselben Daten.
In der folgenden Abbildung sind die FLOPs dargestellt, die mit einem naiven Algorithmus für die Matrixaddition und die Matrixmultiplikation in einem Intel i5-9300H erzielt wurden:
Man beachte, dass die Leistung der Matrixmultiplikation erwartungsgemäß größer ist als die der Matrixaddition. Diese Ergebnisse können reproduziert werden, indem man test/gemm
y test/matadd
verfügbar in diesem Repository .
Ich schlage vor, dass Sie sich auch die Video von J. Dongarra über diesen Effekt.
0 Stimmen
Wenn der Speicher gebunden ist, ist das ein Problem: stackoverflow.com/questions/11831844/