Wie viele Speicheradressen kann der RAM in meinem Computer halten?
Irgendwann macht es Spaß, die Oberfläche des Computererlebnisses zu betrachten, und an anderen Tagen macht es Spaß, direkt in die inneren Abläufe einzutauchen. Heute werfen wir einen Blick auf die Struktur des Computerspeichers und wie viel Sie in einen RAM-Speicher packen können.
Die heutige Question & Answer-Sitzung wird dank SuperUser zur Verfügung gestellt - einer Unterteilung von Stack Exchange, einer Community-basierten Gruppierung von Q & A-Websites.
Die Frage
Der Superuser-Leser Johan Smohan beschäftigt sich mit dem Zusammenwirken von Prozessortyp und Speichergröße, um eine Gesamtzahl von Adressen zu erhalten. Er schreibt:
Wie viele Speicheradressen können wir mit einem 32-Bit-Prozessor und 1 GB RAM erhalten und wie viele mit einem 64-Bit-Prozessor?
Ich denke, dass es ungefähr so ist:
1 GB RAM wird durch 32 Bits (4 Bits) geteilt, um die Anzahl der Speicheradressen zu erhalten?
Ich habe auf Wikipedia gelesen, dass 1 Speicheradressen 32 Bit breit oder 4 Oktette (1 Oktett = 8 Bit) sind, im Vergleich zu einem 64 Bit Prozessor, bei dem 1 Speicheradresse oder 1 Ganzzahl 64 Bit breit oder 8 Oktette ist. Weiß aber nicht, ob ich es richtig verstanden habe.
Mit diesen Fragen kann man nachts neugierig bleiben. Wie viele Adressen stehen unter jedem hypothetischen System von Johan zur Verfügung??
Die Antwort
Der SuperUser-Mitwirkende Gronostaj bietet Einblick in die Aufteilung und Verwendung des Arbeitsspeichers:
Kurze Antwort: Die Anzahl der verfügbaren Adressen ist gleich der kleineren von diesen:
- Speichergröße in Bytes
- Größte vorzeichenlose Ganzzahl, die im Maschinenwort der CPU gespeichert werden kann
Lange Antwort und Erklärung des Vorstehenden:
Der Speicher besteht aus Bytes (B). Jedes Byte besteht aus 8 Bits (b).
1 B = 8 b
1 GB RAM ist eigentlich 1 GiB (Gibibyte, nicht Gigabyte). Der Unterschied ist:
1 GB = 10 ^ 9 B = 1 000 000 000 B 1 GiB = 2 ^ 30 B = 1 073 741 824 B
Jedes Byte des Speichers hat eine eigene Adresse, egal wie groß das CPU-Maschinenwort ist. Z.B. Die Intel 8086-CPU war 16 Bit groß und adressierte den Speicher in Bytes, ebenso wie die modernen 32-Bit- und 64-Bit-CPUs. Das ist die Ursache für das erste Limit - Sie können nicht mehr Adressen als Speicherbytes haben.
Die Speicheradresse ist nur eine Anzahl von Bytes, die die CPU vom Anfang des Speichers aus überspringen muss, um zu dem gesuchten Speicherplatz zu gelangen.
- Um auf das erste Byte zuzugreifen, muss es 0 Byte überspringen, daher ist die Adresse des ersten Byte 0.
- Um auf das zweite Byte zuzugreifen, muss es 1 Byte überspringen, daher lautet seine Adresse 1.
- (und so weiter… )
- Um auf das letzte Byte zuzugreifen, überspringt die CPU 1073741823 Bytes, daher lautet ihre Adresse 1073741823.
Jetzt müssen Sie wissen, was 32-Bit eigentlich bedeutet. Wie ich bereits erwähnt habe, ist es die Größe eines Maschinenwortes.
Maschinenwort ist die Menge an Speicher, die CPU zum Speichern von Zahlen verwendet (im RAM, im Cache oder in internen Registern). 32-Bit-CPU verwendet 32 Bits (4 Bytes) zum Speichern von Zahlen. Speicheradressen sind ebenfalls Zahlen. Bei einer 32-Bit-CPU besteht die Speicheradresse aus 32 Bit.
Denken Sie jetzt darüber nach: Wenn Sie ein Bit haben, können Sie zwei Werte speichern: 0 oder 1. Fügen Sie ein weiteres Bit hinzu, und Sie haben vier Werte: 0, 1, 2, 3. Auf drei Bits können Sie acht Werte speichern : 0, 1, 2… 6, 7. Dies ist eigentlich ein binäres System und es funktioniert so:
Binär dezimal 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001 101010 11 1011 12 1100 13 1101 14 1110 15 1111
Es funktioniert genau wie üblich, aber die maximale Ziffer ist 1, nicht 9. Dezimal 0 ist
0000
, dann addierst du 1 und bekommst0001
, füge noch einmal hinzu und du hast0010
. Was hier passiert ist, ist wie mit Dezimalzahlen09
und fügen Sie eins hinzu: Sie ändern 9 in 0 und erhöhen die nächste Ziffer.Im obigen Beispiel können Sie sehen, dass es immer einen maximalen Wert gibt, den Sie in einer Anzahl mit einer konstanten Anzahl von Bits beibehalten können. Wenn alle Bits 1 sind und Sie versuchen, den Wert um 1 zu erhöhen, werden alle Bits 0 und brechen somit Nummer. Es wird als Ganzzahlüberlauf bezeichnet und verursacht sowohl für Benutzer als auch für Entwickler viele unangenehme Probleme.
11111111 = 255 + 1 ----------- 100000000 = 0 (hier 9 Bits, also wird 1 getrimmt)
- Für 1 Bit ist der größte Wert 1,
- 2 Bits - 3,
- 3 Bits - 7,
- 4 Bits - 15
Die größtmögliche Anzahl ist immer 2 ^ N-1, wobei N die Anzahl der Bits ist. Wie bereits erwähnt, ist eine Speicheradresse eine Zahl und sie hat auch einen Maximalwert. Daher ist die Größe des Computerworts auch eine Begrenzung für die Anzahl der verfügbaren Speicheradressen - manchmal kann Ihre CPU nur Zahlen verarbeiten, die groß genug sind, um mehr Speicher zu adressieren.
Bei 32 Bits können Sie also Zahlen von 0 bis 2 ^ 32-1 beibehalten, und das sind 4 294 967 295. Dies ist mehr als die größte Adresse in 1 GB RAM. In Ihrem speziellen Fall ist die Menge an RAM der limitierende Faktor.
Die RAM-Grenze für 32-Bit-CPU liegt theoretisch bei 4 GB (2 ^ 32) und für 64-Bit-CPU bei 16 EB (Exabyte, 1 EB = 2 ^ 30 GB). Mit anderen Worten, eine 64-Bit-CPU könnte das gesamte Internet… 200-mal ansprechen;) (geschätzt von WolframAlpha).
In realen Betriebssystemen können 32-Bit-CPUs jedoch etwa 3 GB RAM ansprechen. Das liegt an der internen Architektur des Betriebssystems - einige Adressen sind für andere Zwecke reserviert. Weitere Informationen zu dieser sogenannten 3-GB-Barriere finden Sie auf Wikipedia. Sie können dieses Limit mit Physical Address Extension aufheben.
Apropos Speicheradressierung, es gibt ein paar Dinge, die ich erwähnen sollte: virtueller Speicher, Segmentierung und paging.
Virtueller Speicher
Wie @Daniel R Hicks in einer anderen Antwort darauf hinwies, verwenden Betriebssysteme virtuellen Speicher. Das bedeutet, dass Anwendungen eigentlich nicht mit realen Speicheradressen arbeiten, sondern mit denen, die vom Betriebssystem bereitgestellt werden.
Diese Technik ermöglicht es dem Betriebssystem, einige Daten vom RAM in ein sogenanntes Pagefile (Windows) oder Swap (* NIX) zu verschieben. Die Festplatte ist um einige Größen langsamer als der RAM-Speicher, jedoch ist dies kein ernsthaftes Problem für Daten, auf die selten zugegriffen wird, und es ermöglicht dem Betriebssystem, Anwendungen mehr RAM bereitzustellen, als Sie tatsächlich installiert haben.
Paging
Worüber wir bisher gesprochen haben, nennt man das flache Adressierungsschema.
Paging ist ein alternatives Adressierungsschema, das es erlaubt, mehr Speicher zu adressieren, als Sie normalerweise mit einem Maschinenwort in einem flachen Modell hätten.
Stellen Sie sich ein Buch mit vier Buchstaben vor. Angenommen, es gibt auf jeder Seite 1024 Zahlen. Um eine Nummer anzusprechen, müssen Sie zwei Dinge wissen:
- Die Nummer der Seite, auf der das Wort gedruckt wird.
- Welches Wort auf dieser Seite ist das, nach dem Sie suchen.
Genau so gehen moderne x86-CPUs mit Speicher um. Es ist in 4 KiB-Seiten (jeweils 1024 Maschinenwörter) unterteilt, und diese Seiten haben Nummern. (Eigentlich können Seiten auch 4 MiB groß oder 2 MiB mit PAE sein). Wenn Sie eine Speicherzelle ansprechen möchten, benötigen Sie die Seitennummer und Adresse auf dieser Seite. Beachten Sie, dass jede Speicherzelle von genau einem Zahlenpaar referenziert wird. Dies ist bei der Segmentierung nicht der Fall.
Segmentierung
Nun, dieser ist dem Paging ziemlich ähnlich. Es wurde in Intel 8086 verwendet, um nur ein Beispiel zu nennen. Adressgruppen werden jetzt als Speichersegmente bezeichnet, nicht als Seiten. Der Unterschied besteht darin, dass Segmente sich überlappen können, und sie überlappen sich sehr. Zum Beispiel waren bei 8086 die meisten Speicherzellen aus 4096 verschiedenen Segmenten verfügbar.
Ein Beispiel:
Nehmen wir an, wir haben 8 Bytes Speicher, die alle Nullen enthalten, mit Ausnahme des vierten Bytes, das gleich 255 ist.
Abbildung für ein flaches Speichermodell:
_____ | 0 | | 0 | | 0 | | 255 | | 0 | | 0 | | 0 | | 0 | -----
Illustration für ausgelagerten Speicher mit 4-Byte-Seiten:
SEITE0 _____ | 0 | | 0 | | 0 | SEITE1 | 255 | _____ ----- | 0 | | 0 | | 0 | | 0 | -----
Illustration für segmentierten Speicher mit um 1 Byte verschobenen 4-Byte-Segmenten:
SEG 0 _____ SEG 1 | 0 | _____ SEG 2 | 0 | | 0 | _____ SEG 3 | 0 | | 0 | | 0 | _____ SEG 4 | 255 | | 255 | | 255 | | 255 | _____ SEG 5 ----- | 0 | | 0 | | 0 | | 0 | _____ SEG 6 ----- | 0 | | 0 | | 0 | | 0 | _____ SEG 7 ----- | 0 | | 0 | | 0 | | 0 | _____ ----- | 0 | | 0 | | 0 | | 0 | ----- ----- ----- -----
Wie Sie sehen, kann das vierte Byte auf vier Arten adressiert werden: (Adressierung von 0)
- Segment 0, Offset 3
- Segment 1, Versatz 2
- Segment 2, Versatz 1
- Segment 3, Versatz 0
Es ist immer die gleiche Speicherzelle.
In realen Implementierungen werden Segmente um mehr als 1 Byte verschoben (für 8086 waren es 16 Byte)..
Das Schlechte an der Segmentierung ist, dass sie kompliziert ist (aber ich denke, dass Sie das bereits wissen;) Was gut ist, ist, dass Sie einige clevere Techniken verwenden können, um modulare Programme zu erstellen.
Sie können beispielsweise ein Modul in ein Segment laden und dann vorgeben, dass das Segment kleiner ist als es tatsächlich ist (gerade klein genug, um das Modul zu halten). Wählen Sie dann das erste Segment aus, das sich nicht mit dem kleineren Pseudo-Segment überschneidet, und laden Sie anschließend das nächste Modul und so weiter. Grundsätzlich erhalten Sie auf diese Weise Seiten mit variabler Größe.
Haben Sie der Erklärung etwas hinzuzufügen? Ton aus in den Kommentaren. Möchten Sie mehr Antworten von anderen technisch versierten Stack Exchange-Benutzern lesen? Hier geht es zum vollständigen Diskussionsthread.