Warum müssen wir auf I / O warten?


28

Es ist seit jeher bekannt, dass Festplattenvorgänge langsam sind, und wir kennen die Gründe, warum sie langsam sind. Die Frage hier ist also, warum wir auf I / O warten müssen oder warum es so etwas wie IOWait usw. gibt.

Ich habe gemerkt, dass bei der Ausführung einiger E / A-Aufgaben im Hintergrund Ihr Computer im Grunde genommen sehr viel langsamer wird. Insbesondere bei der Verwendung von Linux ist mir aufgefallen, dass Sie längere E / A-Aufgaben ausführen wird das Betriebssystem fast unbrauchbar, bis sie abgeschlossen sind.

Tatsächlich habe ich dieses Thema auch in einem Artikel gefunden, es gibt einen Ausschnitt:

Die E / A-Wartezeit beträgt 12,1%. Dieser Server hat 8 Kerne (via cat / proc / cpuinfo). Dies ist sehr nahe (1/8 Kerne = 0,125)

Im Grunde bedeutet dies, dass der Computer VIEL langsamer wird. Warum ist das so? Ich meine OK, jetzt sind die normalen Computer mindestens 2 Kerne, manchmal 4 oder manchmal haben sie mehr wegen Hyperthreading oder so ähnlich. Jetzt stellt sich die Frage, warum die CPU eigentlich dort bleiben muss und praktisch nichts anderes tut, als nur auf IO zu warten. Ich meine die Grundidee oder Architektur des Prozessmanagements, jetzt weiß ich nicht, ob es das Betriebssystem ist, das dafür verantwortlich ist, oder ob es auf den Hardwareteil ankommt, aber es sollte der CPU ermöglicht werden, zu warten oder zu warten Überprüfen Sie dies regelmäßig, während Sie viele andere Aufgaben ausführen und erst dann zum E / A-Prozess zurückkehren, wenn er fertig ist. In der Tat, wenn das eine so schwierige Aufgabe ist und die CPU warten müsste, warum nicht? Ist das mit Hardware effizienter? Zum Beispiel könnte es eine Art Mini-CPU geben, die nur darauf wartet und den kleinen Teil der Daten an die echte CPU liefert, sobald sie wieder in den Prozess eingehen, und so würde der Prozess wiederholt und wir hätten es nicht getan praktisch einen ganzen CPU-Kern für den Datenkopierprozess zu widmen ... Oder wäre ich derjenige, der solche Sachen erfinden und dafür einen Nobelpreis bekommen sollte? : S

Okay, ich sage es jetzt wirklich aus der Perspektive eines Beobachters und ich habe mich nicht so tief mit dem Thema befasst, aber ich verstehe wirklich nicht, warum die CPU mit der Geschwindigkeit der Festplatte arbeiten muss, obwohl es nur möglich ist Tun Sie etwas anderes und kehren Sie zur Festplatte zurück, sobald sie fertig ist. Die Idee ist nicht, die Anwendung zu beschleunigen, die diese E / A-Operation oder den Kopiervorgang oder was auch immer benötigt, sondern den CPU-Verbrauch während dieser Operation nur minimal zu beeinflussen, damit das Betriebssystem ihn für andere Prozesse und den Benutzer verwenden kann Ich müsste beim Kopieren keine allgemeine Verzögerung des Computers spüren ...


41
"während es nur etwas anderes tun könnte" - wie? Es muss mit Daten arbeiten. Wenn sich diese Daten nicht im L1-Cache der CPU befinden, müssen sie aus dem L2-Cache abgerufen werden. Wenn es sich nicht im L2-Cache befindet, muss es vom L3 abgerufen werden (falls vorhanden). Wenn es sich überhaupt nicht in den On-Die-Caches befindet, muss es auf den Hauptspeicher zugreifen. Wenn nicht im Hauptspeicher ... muss auf die Festplatte zugegriffen werden.
Oded

39
Der Computer macht etwas anderes; Der Kernel blockiert den Thread, bis die E / A-Operation abgeschlossen ist, sodass andere Threads / Prozesse ausgeführt werden können. Aber wenn alles auf dem Datenträger wartet, gibt es nichts anderes zu tun.
Colonel Zweiunddreißig

6
Sie müssen warten, bis die Programme den E / A-Turm erreichen und Ihnen ihre Frisbees schicken!
Almo

1
@immibis Richtig! :)
Almo

2
In der Regel tun moderne Betriebssysteme das, worüber Sie sich beschweren - E / A-Vorgänge werden an die entsprechende Hardware gesendet, und von der Hardware werden Interrupts generiert, um anzuzeigen, dass die Vorgänge ausgeführt wurden. Prozesse, die auf IO warten, werden normalerweise während des Wartens blockiert (dies kann geändert werden). Wenn viele Prozesse auf E / A warten und keine anderen Prozesse etwas für die CPU zu tun haben, gibt es nicht viel zu tun. Sie könnten auch in der Mem-Swap-Hölle enden. Das Schreiben von Programmen zur effizienten Auslastung von CPU, Arbeitsspeicher und E / A erfordert besondere Kenntnisse, und was sonst noch ausgeführt wird, wirkt sich auch auf das aus, was am besten funktioniert.
Nategoose

Antworten:


19

Die von Ihnen beschriebenen E / A-Schemata werden derzeit auf Computern verwendet.

warum muss die CPU eigentlich dort bleiben und praktisch nichts anderes tun, als nur auf IO zu warten?

Dies ist die einfachste mögliche I / O - Methode: programmierte I / O . Viele eingebettete Systeme und Low-End-Mikroprozessoren haben nur einen einzigen Eingabebefehl und einen einzigen Ausgabebefehl. Der Prozessor muss für jedes gelesene oder geschriebene Zeichen eine explizite Folge von Anweisungen ausführen.

Es sollte jedoch möglich sein, dass die CPU wartet oder regelmäßig prüft, während sie viele andere Aufgaben ausführt und erst dann zum E / A-Prozess zurückkehrt, wenn dieser bereit ist

Viele PCs verfügen über andere E / A-Schemata. Anstatt in einer engen Schleife darauf zu warten , dass das Gerät bereit ist ( ausgelastetes Warten ), startet die CPU das E / A-Gerät und fordert es auf, nach Abschluss einen Interrupt zu generieren ( Interrupt-gesteuerte E / A ).

Obwohl die Interrupt-gesteuerte E / A ein Fortschritt ist (im Vergleich zur programmierten E / A), erfordert sie einen Interrupt für jedes übertragene Zeichen und ist teuer ...

Zum Beispiel könnte es eine Art Mini-CPU geben, die nur darauf wartet und den kleinen Teil der Daten an die echte CPU liefert, sobald sie wieder in den Prozess eingehen, und so würde der Prozess wiederholt und wir hätten es nicht getan praktisch einen ganzen CPU-Kern für den Datenkopierprozess zu widmen ...

Die Lösung für viele Probleme liegt darin, dass jemand anderes die Arbeit erledigt! :-)

Der DMA-Controller / Chip (Direct Memory Access) ermöglicht programmierte E / A-Vorgänge, die jedoch von einer anderen Person ausgeführt werden können!

Mit DMA muss die CPU nur ein paar Register initialisieren und es ist frei, etwas anderes zu tun, bis die Übertragung beendet ist (und ein Interrupt ausgelöst wird).

Auch DMA ist nicht völlig kostenlos: Hochgeschwindigkeitsgeräte können viele Buszyklen für Speicherreferenzen und Gerätereferenzen verwenden ( Cycle Stealing ) und die CPU muss warten (DMA-Chip hat immer eine höhere Buspriorität).

Die E / A-Wartezeit beträgt 12,1%. Dieser Server hat 8 Kerne (via cat / proc / cpuinfo). Dies ist sehr nahe (1/8 Kerne = 0,125)

Ich denke, das kommt von: Grundlegendes zu Datenträger-E / A - Wann sollten Sie sich Sorgen machen?

Nun, das ist nicht seltsam: Das System (mySQL) muss alle Zeilen abrufen, bevor es Daten manipuliert, und es gibt keine anderen Aktivitäten.

Hier gibt es kein Problem mit der Computerarchitektur / dem Betriebssystem. Es ist nur so, wie das Beispiel gesetzt ist.

Es kann sich höchstens um ein RDBMS-Optimierungsproblem oder ein SQL-Abfrageproblem handeln (fehlender Index, fehlerhafter Abfrageplan, fehlerhafte Abfrage ...)


24

Es ist möglich, asynchrone E / A-Vorgänge zu schreiben, bei denen Sie das Betriebssystem anweisen, eine Lese- / Schreiboperation für die Festplatte auszuführen, dann etwas anderes zu tun und später zu überprüfen, ob dies abgeschlossen ist. Es ist alles andere als neu. Eine ältere Methode verwendet einen anderen Thread für die E / A.

Dies setzt jedoch voraus, dass Sie etwas zu tun haben, während dieser Lesevorgang ausgeführt wird, und dass Sie den Puffer, den Sie für das Ergebnis übergeben haben, nicht berühren dürfen.

Es ist auch viel einfacher zu programmieren, wenn Sie davon ausgehen, dass alles IO blockiert.

Wenn Sie eine Sperrlesefunktion rufen Sie wissen , es wird bestätigt , bis etwas gelesen wurde und unmittelbar nach der Verarbeitung können Sie auf starten.

Die typische Leseschleife ist ein gutes Beispiel

//variables that the loop uses
char[1024] buffer;
while((read = fread(buffer, 1024, 1, file))>0){
    //use buffer
}

Andernfalls müssen Sie den aktuellen Funktionsstatus (normalerweise in Form eines Rückrufs + userData-Zeigers) speichern und ihn + Kennung der Leseoperation zurück an eine select()Typschleife übergeben. Wenn eine Operation beendet ist, ordnet sie die Kennung der Leseoperation dem Rückruf + Datenzeiger zu und ruft den Rückruf mit Informationen über die abgeschlossene Operation auf.

void callback(void* buffer, int result, int fd, void* userData){
    if(result<=0){
    //done, free buffer and continue to normal processing
    }
    //use buffer

    int readID = async_read(fd, buffer, userData->buff_size);
    registerCallback(readId, callback, userData);
}

Dies bedeutet auch, dass jede Funktion, die diesen asynchronen Lesevorgang verwenden könnte, in der Lage sein muss, eine asynchrone Fortsetzung zu verarbeiten. Das ist eine nicht triviale Änderung in den meisten Programmen. Sie fragen die Leute, die versuchen, sich in asynchrones C # zu verwandeln.


Synchrones E / A im Vergleich zu asynchronem E / A ist jedoch nicht die Ursache für die allgemeine Verlangsamung. Das Einlagern von Seiten ist auch eine Operation, die auf E / A warten muss. Der Scheduler wechselt nur zu einem anderen Programm, das nicht auf E / A wartet, wenn dies der Fall ist ( E / A-Wartezeit liegt vor, wenn der Prozessor inaktiv ist und eine E / A-Operation ansteht ).

Das eigentliche Problem besteht darin, dass sowohl die Festplatte als auch die CPU denselben Kanal für die Kommunikation mit dem RAM verwenden . der Speicherbus. Und es sei denn, Sie verwenden RAID, gibt es nur eine einzige Festplatte, von der Sie die Daten abrufen können. Dies wird noch verschlimmert, wenn Sie auch eine grafikintensive Anwendung verwenden. Dann wird auch die Kommunikation mit der GPU gestört.

Mit anderen Worten, der wahre Engpass liegt wahrscheinlich eher in der Hardware als in der Software.


6
"Allerdings ist synchrone E / A im Vergleich zu asynchronen E / A nicht die Ursache für die allgemeine Verlangsamung." Warum haben Sie sich dann für dieses relativ fortgeschrittene Thema entschieden, wenn es um die Grundlagen geht?
Svick

1
Sie sollten wahrscheinlich etwas über DMA erwähnen
Alec Teal

2
Tolles Faktum: Es gibt einen wirklich alten Mechanismus, mit dem Programme während der E / A-Vorgänge etwas anderes tun können, ohne Rückrufe verarbeiten zu müssen. Es heißt Threads .
user253751

2
Gute Diskussion über die Vor- und Nachteile von Sync / Async IO. Aber sind Sie sicher, dass dies der Grund für die Verlangsamung ist? Im Allgemeinen stelle ich fest, dass Verzögerungen bei hoher E / A-Belastung zum einen auf schlecht entwickelte Software zurückzuführen sind, oder, wenn dies nicht der Fall ist, auf eine einzige langsame Festplatte (dh eine Nicht-SSD), auf die alle gleichzeitig zugreifen möchten . Ich würde einen Engpass für die Fähigkeit der Festplatte zur Bearbeitung von Anfragen verantwortlich machen, bevor ich die Sättigung des Speicherbusses dafür verantwortlich machen würde. Sie benötigen wirklich High-End-Speicher, um einen modernen Speicherbus zu sättigen.
Aroth

9

Gehen Sie davon aus, dass die Verarbeitung anderer Dinge beim Warten auf E / A-Vorgänge rationalisiert ist, fast so rationalisiert wie möglich. Wenn Sie feststellen, dass Ihr Computer nur in 12,1% der Fälle auf E / A wartet, bedeutet dies, dass viele andere Dinge parallel ausgeführt werden. Wenn es wirklich auf I / O warten müsste, ohne etwas anderes zu tun, würde es 99,9% der Zeit warten, so langsam ist I / O.

Die einzige Möglichkeit, mehr Dinge gleichzeitig zu tun, besteht darin, vorherzusagen, was der Benutzer als Nächstes tun möchte, und wir sind noch nicht sehr gut in dieser Art von Vorhersage. Wenn der Benutzer also einen Vorgang ausführt, bei dem ein bestimmter Sektor von der Festplatte gelesen werden muss und dieser Sektor sich noch nicht im Cache befindet, beginnt das Betriebssystem mit dem sehr langen Prozess des Lesens dieses Sektors und dieses Sektors Ich werde versuchen zu sehen, ob in der Zwischenzeit noch etwas zu tun ist. Wenn es einen anderen Benutzer gibt, der einen anderen Sektor haben möchte, wird diese Anforderung ebenfalls in die Warteschlange gestellt. Irgendwann wurden alle Anforderungen in die Warteschlange gestellt, und wir können nichts anderes tun, als darauf zu warten, dass die erste erfüllt wird, bevor wir fortfahren können. Es ist nur eine Tatsache des Lebens.

BEARBEITEN:

Es wäre eine bewundernswerte Leistung, eine Lösung für das Problem zu finden, wie man andere Dinge im Leerlauf erledigt. Eine erstaunliche Leistung, denn es würde bedeuten, dass Sie Arbeit für Ihren Computer finden würden, während er keine hat.

Sie sehen, das ist, was passiert: Ihr Computer sitzt nur 99,99% der Zeit und tut nichts. Wenn du ihm etwas zu tun gibst, geht es und tut es. Wenn es dabei auf I / O warten muss, sitzt es dort und wartet. Wenn es während der E / A-Vorgänge noch etwas anderes zu tun hat, tut es dies auch. Aber wenn es außer E / A nichts anderes zu tun hat, muss es dort sitzen und warten, bis die E / A abgeschlossen ist. Es gibt keine andere Möglichkeit, dies zu umgehen, als sich bei SETI @ Home anzumelden.


Nun, das Beispiel mit 12,1% stammt von einer Website und das Beispiel wurde von einem Server mit 8 Kernen aufgenommen. Es bestand die Idee, dass fast ein ganzer Kern nur für diese Operationen reserviert war. Sicher, dass die anderen Kerne für alles frei waren und 8 Kerne hatten Ihnen geht es gut, aber was ist, wenn Sie nur einen Kern haben? : /
Arturas M

3
@ArturasM Entweder haben Sie falsch verstanden, was die Website sagt, oder der Autor der Website hat etwas falsch verstanden. Ein Computer mit nur einem Kern würde weniger Zeit für E / A-Vorgänge aufwenden (da alle Aufgaben, die nicht auf E / A warten und auf den anderen Kernen ausgeführt werden, während ein Kern im Leerlauf ist, alle auf dem Kern ausgeführt werden müssten) Ader). Es dauert eine gewisse Zeit, bis die E / A ausgeführt wird, unabhängig davon, ob Sie darauf warten oder nicht. Das Abwarten ist ein Symptom dafür, dass mit dieser Zeit nichts anderes zu tun hat.
Random832

6

Das Betriebssystem (es sei denn, es ist ein Embedded-System auf sehr niedriger Ebene oder etwas ähnlich Exotisches) kümmert sich bereits darum: Wenn Ihre Anwendung auf E / A warten muss, blockiert es normalerweise diese E / A, und es wird ein anderer Thread oder eine andere Anwendung aktiv. Der Scheduler entscheidet, welche.

Nur wenn es keinen anderen Thread oder keine andere Anwendung gibt, die ausgeführt werden könnte, erhöht sich die Wartezeit. In dem Artikel, den Sie zitiert haben (danke an @manlio für den Link), ist dies der Fall: Sie haben 12,1% Wartezeit gegenüber 87,4% Leerlauf, was bedeutet, dass ein Core darauf wartet, dass die E / A abgeschlossen sind, während der Rest nichts tut überhaupt. Geben Sie diesem System etwas zu tun, vorzugsweise mehrere Dinge, und der Prozentsatz der Wartezeit sollte sinken.

Eines der Hauptziele des heutigen Anwendungsdesigns besteht darin, sicherzustellen, dass auch dann, wenn nur eine Anwendung ausgeführt wird und diese einzelne Anwendung irgendwann auf die E / A wartet, die Anwendung auf einem anderen Teil der Arbeit fortgesetzt werden kann. Threads sind der eine Ansatz, nicht blockierende E / A der andere, aber es hängt stark von der Art Ihrer Arbeit ab, ob Sie tatsächlich etwas erledigen können, ohne die Daten, auf die Sie warten.

Wenn Sie unter Linux längere E / A-Aufgaben ausführen, wird das Betriebssystem fast unbrauchbar, bis sie abgeschlossen sind.

Dies ist normalerweise ein Hinweis auf eine E / A-gebundene Situation. Ich wage zu sagen, dass das System nicht langsam wird, weil es nicht genug CPU-Verarbeitung kann. Wahrscheinlicher ist es langsam, da eine Reihe von Dingen von Daten von der Festplatte abhängt, die zu diesem Zeitpunkt ausgelastet ist. Dies können Anwendungen sein, die Sie ausführen möchten, deren ausführbare Dateien, Bibliotheksdateien, Symbole, Schriftarten und andere Ressourcen jedoch geladen werden müssen. Es können Anwendungen sein, die Sie bereits ausgeführt haben, die jedoch einen Teil ihres Speichers ausgelagert haben und die jetzt erneut eingelagert werden müssen, um fortzufahren. Es könnte sich um einen Daemon handeln, der aus dem einen oder anderen Grund der Ansicht ist, dass er nicht nur eine Zeile in eine Protokolldatei schreiben, sondern diese Protokolldatei tatsächlich leeren muss, bevor eine Anfrage beantwortet wird.

Mit Tools können Sie beispielsweise die iotopZuordnung der E / A-Kapazität zu Prozessen und ionicedie E / A-Prioritäten für Prozesse festlegen. Auf einem Desktopcomputer können Sie beispielsweise die gesamte Massendatenverarbeitung der idlePlanungsklasse zuordnen, sodass die Massenverarbeitung angehalten wird, bis die interaktive Anwendung abgeschlossen ist, sobald eine interaktive Anwendung E / A-Bandbreite benötigt.


5

Dies hängt von Ihrem Anwendungscode ab. Ich nehme an, Ihr Code läuft unter Linux.

Sie können Multithreading (z. B. POSIX- Pthreads ) verwenden, damit rechnergebundene Threads einige Berechnungen ausführen, während andere e / a-gebundene Threads die E / A ausführen (und darauf warten). In Ihrer Anwendung können sogar mehrere Prozesse ausgeführt werden , die mit der Interprozesskommunikation (IPC) kommunizieren , siehe pipe (7) , fifo (7) , socket (7) , unix (7) , shm_overview (7) , sem_overview (7) . mmap (2) , eventfd (2) und lies Advanced Linux Programming etc ....

Sie könnten nicht blockierende E / A verwenden , z. B. übergeben O_NOBLOCK, um (2) usw. usw. usw. zu öffnen . dann müssen Sie abfragen (2) und / oder SIGIO Signal (7) verwenden ... und den EWOULDBLOCKFehler von read (2) usw. behandeln.

Sie könnten asynchrone POSIX-E / A verwenden, siehe aio (7).

Für den Dateizugriff können Sie Hinweise auf den Seiten-Cache geben , z. B. mit madvise (2) nach mmap (2) und mit posix_fadvise (2) ; siehe auch den Linux-spezifischen Readahead (2)

Aber irgendwann würden Sie einen Hardware-Engpass erreichen (Bus, RAM usw.). Siehe auch ionice (1)


1

Ich füge andere Gesichtspunkte als andere hinzu, die vielleicht umstritten sind:

Sein typisches Problem von Linux-Betriebssystemen. Speziell verzögert (Suche nach "Linux-Mausverzögerung"). Windows hat dieses Problem nicht. Ich habe Dual Boot Windows 7 und Linux Mint. Selbst wenn Windows einen intensiven Festplattenbetrieb ausführt, fühlt sich Windows flüssig an und die Maus bewegt sich normal. Im Gegensatz zu Linux fühlt es sich nicht so flüssig an und die Maus bleibt manchmal auch beim normalen Surfen im Internet hängen.

Das liegt wahrscheinlich an der unterschiedlichen Philosophie und Geschichte dieser beiden Systeme. Windows ist von Anfang an für normale Benutzer gedacht, seine hauptsächlich grafischen Betriebssysteme. Und für Windows-Benutzer ist ein nicht reibungsloses Systemverhalten und ein Anhalten der Maus ein Signal dafür, dass etwas nicht stimmt. Daher haben die Programmierer von Microsoft hart daran gearbeitet, das gesamte System so zu gestalten, dass Fälle minimiert werden, in denen sich das System langsam anfühlt. Im Gegensatz zu Linux handelt es sich bei dem grafischen System zunächst nicht um ein Drittanbieter-Add-In. Und Linux ist hauptsächlich für Hacker gedacht, die die Befehlszeile verwenden. Erledige die Dinge, Philosophie. Linux ist einfach nicht auf reibungsloses Verhalten ausgelegt, Gefühle spielen hier keine Rolle.

Hinweis: Ich sage nicht, dass Windows besser ist als Linux, ich sage, dass sie einfach eine andere Gesamtphilosophie haben, was in einer komplexen Umgebung zu einem anderen Verhalten / Gefühl dieser Systeme auf hoher Ebene führen kann.


Eine Verzögerung der Linux-Maus könnte wahrscheinlich durch sorgfältige Konfiguration des Systems (z. B. Verwendung von nice& ionicebei hungrigen Prozessen) vermieden oder verringert werden . Und ich benutze Linux und habe fast nie erlebt, dass Linux-
Mausverzögerung

Übrigens ist Linux meistens ein Server-Betriebssystem.
Basile Starynkevitch

Ich stelle fest, dass ich unter Windows 7 eine Verzögerung der Benutzeroberfläche und der Maus festgestellt habe, selbst wenn der Task-Manager und der Ressourcenmonitor auf eine geringe Speichernutzung und geringe CPU- und Festplattenaktivität hinwiesen.
8bittree,
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.