Frage

Es ist eine bekannte Tatsache, dass Windows-Anwendungen in der Regel 2 GB Adressraum auf einem 32-Bit-System der privaten haben. Dieser Raum kann mit der Option / 3GB zu 3Gb erweitert werden.

Das Betriebssystem behält sich das Verbleiben der 4Gb.

Meine Frage ist, warum?

-Code im Kernel-Modus ausgeführt wird (das heißt Gerätetreibercode) hat einen eigenen Adressraum. Warum, auf einem exklusiven 4 GB Adressraum, das Betriebssystem noch 2Gb jedes Benutzermodus-Prozess reservieren möchten?

dachte ich, der Grund dafür ist der Übergang zwischen Benutzermodus und Kernelmodus-Anruf. Zum Beispiel wird ein Aufruf an NtWriteFile benötigt eine Adresse für die Kernel-Dispatch-Routine (daher, warum die Systemreserve 2Gb in jeder Anwendung). Aber mit SYSENTER, ist nicht die System Servicenummer genug für den Kernel-Modus-Code zu wissen, welche Funktion / Dienst aufgerufen wird?

Wenn Sie könnten mir erklären, warum es für das Betriebssystem so wichtig ist, 2Gb zu nehmen (oder 1 Gb) jeden Benutzermodus-Prozesses.

War es hilfreich?

Lösung

Zwei verschiedene Benutzerprozesse haben verschiedene virtuelle Adressräume. Da die virtual↔physical Adreßzuordnungen verschieden sind, die TLB Cache für ungültig erklärt wird, wenn von einem Benutzer Kontexte Schalt Prozess zum anderen. Dies ist sehr teuer, da ohne die Adresse bereits im TLB zwischengespeichert, jeder Speicherzugriff in einem Fehler führen und einen Spaziergang von dem PTE s.

Syscalls beinhalten zwei Kontextwechsel: Benutzer → Kernel und dann Kernel → Benutzer. Um dies zu beschleunigen, ist es üblich, das Top-1 GB oder 2 GB virtuellen Adressraum für die Kernel Verwendung zu reservieren. Da der virtuelle Adressraum nicht über diese Kontextwechsel ändern, ist keine TLB Wallungen notwendig. Dies wird ermöglicht durch ein Benutzer / Supervisor-Bit in jeder PTE, die dafür sorgt, dass Kernel-Speicher nur zugänglich, während in der Kernel- ist; User-Space hat keinen Zugriff, auch wenn die Seitentabelle ist das gleiche.

Wenn Hardware-Unterstützung für zwei getrennte TLBs sind, mit einem ausschließlich für den Kernel verwenden, dann würde diese Optimierung nicht mehr nützlich sein. wenn Sie genügend Platz zu widmen haben jedoch, ist es wahrscheinlich mehr wert, nur ein macht größer TLB.

Linux auf x86 unterstützt einmal einen Modus als "4G / 4G split" bekannt. In diesem Modus haben User-Space vollen Zugriff auf den gesamten virtuellen Adressraum 4 GB, und der Kern hat auch einen vollen Raum virtuelle Adresse 4 GB. Die Kosten, wie oben erwähnt, ist, dass alle syscall einen TLB-Leerungs erfordert, zusammen mit komplexeren Routinen Daten zwischen Benutzer und Kernel-Speicher zu kopieren. Dies wurde zu einer 30% igen Leistungseinbuße zu verhängen bis gemessen.


Die Zeiten haben sich geändert, da diese Frage wurde ursprünglich gestellt und beantwortet: 64-Bit-Betriebssysteme sind jetzt viel häufiger. In aktuellen Betriebssysteme auf x86-64, virtuelle Adressen von 0 bis 2 47 -1 (0-128TB) für Anwenderprogramme erlaubt werden, während der Kern in virtuellen Adressen von 2 befindet sich permanent 47 × (2 17 -1) bis 2 64 -1 (oder von -2 47 -1, wenn Sie behandeln Adressen unterzeichnet ganze Zahlen).

Was passiert, wenn Sie ein 32-Bit-Programm auf einem 64-Bit-Windows laufen? Sie würden denken, dass alle virtuellen Adressen von 0 bis 2 32 (0-4GB) leicht verfügbar sein würde, aber um Fehler in den bestehenden Programmen zu vermeiden aussetzt, 32-Bit-Programme noch auf 0- begrenzt 2GB es sei denn, sie sind mit /LARGEADDRESSAWARE neu kompiliert. Für diejenigen, die sind, sie Zugang zu 0-4GB bekommen. (Dies ist keine neue Flagge, die angewendet gleiches in 32-Bit-Windows-Kernel mit dem /3GB Schalter ausgeführt wird, die den Standard geändert 2G / 2G Benutzer / kernel Split 3G / 1G, obwohl natürlich 3-4GB noch aus sein würde, Bereich).

Welche Arten von Bugs könnte es sein? Als ein Beispiel: Angenommen, Sie quicksort und haben zwei Zeiger, a und b zeigen zu Beginn und nach dem Ende eines Arrays implementieren. Wenn Sie die Mitte als Drehpunkt mit (a+b)/2 wählen, wird es funktionieren, solange beide die Adressen unter 2 GB sind, aber wenn sie beide oben sind, dann wird die Zugabe Integer-Überlauf auftreten und das Ergebnis wird außerhalb des Arrays sein. (Der richtige Ausdruck ist a+(b-a)/2.)

Als beiseite, 32-Bit-Linux, mit seiner Standard-3G / 1G Benutzer / kernel Split, hat in der Vergangenheit laufen Programme mit ihren Stack im Bereich 2-3GB gelegen, so dass solcher Programmierfehler wäre wahrscheinlich schnell ausgespült werden . 64-Bit-Linux gibt 32-Bit-Programme Zugriff auf 0-4GB.

Andere Tipps

Fenster (wie jedes O) ist viel mehr, als der Kernel + Treiber.

Ihre Anwendung setzt auf vielen OS-Dienste, die nicht nur im Kernel-Raum existieren. Es gibt eine Menge von Puffern, Griffen und alle Arten von Ressourcen, die zu Ihren Prozess eigenen Adressraum erhalten abgebildet werden. Jedes Mal, wenn Sie eine Win32-API-Funktion aufrufen, die, sagen wir, ein Fenster-Handle zurückgibt, oder eine Bürste, haben diese Dinge irgendwo in Ihrem Prozess zugeordnet werden. So Teil von Windows läuft im Kernel, ja, laufen andere Teile in den eigenen User-Mode-Prozessen, und einige, die, die Ihre Anwendung direkten Zugriff auf, abgebildet werden auf Ihren Adressraum. Ein Teil davon ist schwer zu vermeiden, aber ein wichtiger zusätzlicher Faktor ist die Leistung. Wenn alle Win32 Anruf einen Kontextwechsel erforderlich ist, wäre es eine große Leistung Hit. Wenn einige von ihnen können in Usermode behandelt werden, da die Daten, die sie sich verlassen bereits mit dem Adressraum abgebildet ist, wird der Kontextwechsel vermieden und Sie schon einige CPU-Zyklen speichern.

So alle OS Bedürfnisse einig Menge des Adressraumes beiseite stellen. Ich glaube, Linux standardmäßig setzt nur 1 GB für das Betriebssystem.

Der Grund, warum MS auf 2 GB ließ sich mit Windows auf Raymond Chen Blog einmal erklärt wurde. Ich habe nicht den Link, und ich kann die Details nicht mehr erinnern, aber die Entscheidung wurde getroffen, weil Windows NT ursprünglich auf Alpha-Prozessoren als auch gezielt wurde, und auf Alpha, gibt es einig wirklich guten Grund, die 50/50 zu tun Teilt. ;)

Es war etwas mit der Alpha-Unterstützung für 32 sowie 64-Bit-Code zu tun. :)

  

-Code im Kernel-Modus ausgeführt wird (dh Gerätetreibercode) hat einen eigenen Adressraum ist.

Nein, es nicht. Es hat sich Adreßraum mit dem Benutzermodus-Teil eines Prozesses auf x86-Prozessoren zu teilen. Deshalb haben die Kernel-Raum genug insgesamt zu behalten haben und den Adressraum endlich ist.

Ich glaube, die beste Antwort ist, dass die OS-Designer das Gefühl, dass man durch die Zeit kümmern würde, würden die Leute 64-Bit-Windows verwendet werden.

Aber hier ist ein besser Diskussion .

Ein Teil der Antwort ist mit der Geschichte der Mikroprozessor-Architekturen zu tun. Hier einige von dem, was ich weiß, können andere neuere weitere Einzelheiten bekannt.

Der Intel 8086 Prozessor hatte eine Segment-Offset Architektur für Speicher, 20-Bit-Speicheradressen geben, und somit insgesamt adressierbaren physischen Speicher von 1 MB.

Im Gegensatz zu Prozessoren der Ära im Wettbewerb - wie die Zilog Z80 - das Intel 8086 hatte nur einen Adressraum , die nicht nur elektronische Speicher zur Aufnahme hatte, aber alle Eingabe / Ausgabe-Kommunikation mit solchen kleineren Peripheriegeräten wie Tastatur, serielle Anschlüsse, Druckeranschlüsse und Video-Displays. (Zum Vergleich hatte die Zilog Z80 über einen separaten Eingang / Ausgang-Adressraum mit spezieller Montage Opcodes für den Zugang)

Die Notwendigkeit, damit Platz für einen stetig wachsenden Bereich der peripheren Erweiterungen führten zu der ursprünglichen Entscheidung Segment des Adressraum in einem elektronischen Speicher von 0-640K, und „anderen Sachen“ (Input / Output, ROMS, Videospeicher, etc.) von 640K bis 1MB.

Da die x86-Linie wuchs und entwickelte sich, und PCs mit ihnen entwickelt haben ähnliche Systeme verwendet worden, mit der heutigen 2G / 2G Spaltung des Adressraums 4G endet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top