Hoeveel geheugenadressen kan het RAM-geheugen in mijn computer bevatten?
Op een dag is het leuk om naar het oppervlakniveau van de computerervaring te kijken, en op andere dagen is het leuk om je in de interne werking te verdiepen. Vandaag bekijken we de structuur van het computergeheugen en hoeveel dingen je in een RAM-geheugen kunt stoppen.
De Question & Answer-sessie van vandaag komt tot ons dankzij SuperUser - een onderdeel van Stack Exchange, een gemeenschapsgedreven groep van Q & A-websites.
De vraag
SuperUser-lezer Johan Smohan worstelt met de manier waarop het type processor en het geheugen samenwerken om een totaal aantal adressen te krijgen. Hij schrijft:
Hoeveel geheugenadressen kunnen we krijgen met een 32-bits processor en 1GB ram en hoeveel met een 64-bits processor?
Ik denk dat het zoiets is als dit:
1 GB ram gedeeld door 32 bits 4 bits (?) Om het aantal geheugenadressen te krijgen?
Ik lees op Wikipedia dat 1 geheugenadressen 32 bits breed of 4 octetten (1 octet = 8 bits) zijn, vergeleken met een 64-bits processor waarbij 1 geheugenadres of 1 integer 64 bits breed of 8 octetten is. Maar ik weet ook niet of ik het goed heb begrepen.
Dit zijn de soorten vragen die een nieuwsgierige geek 's nachts wakker kunnen houden. Hoeveel adressen zijn er beschikbaar onder elk van de hypothetische systemen van Johan??
Het antwoord
SuperUser-bijdrager Gronostaj biedt enig inzicht in hoe de RAM wordt verdeeld en gebruikt:
Kort antwoord: Het aantal beschikbare adressen is gelijk aan het kleinere aantal:
- Geheugengrootte in bytes
- Het grootste niet-ondertekende gehele getal dat kan worden opgeslagen in het machinewoord van de CPU
Lang antwoord en uitleg van het bovenstaande:
Geheugen bestaat uit bytes (B). Elke byte bestaat uit 8 bits (b).
1 B = 8 b
1 GB RAM is eigenlijk 1 GiB (gibibyte, niet gigabyte). Het verschil is:
1 GB = 10 ^ 9 B = 1 000 000 000 B 1 GiB = 2 ^ 30 B = 1 073 741 824 B
Elke byte van het geheugen heeft een eigen adres, ongeacht hoe groot het woord van de CPU-machine is. Bijv. Intel 8086 CPU was 16 bit en het werkte geheugen door bytes, net als moderne 32-bit en 64-bit CPU's. Dat is de oorzaak van de eerste limiet - u kunt niet meer adressen hebben dan geheugenbytes.
Het geheugenadres is slechts een aantal bytes dat de CPU vanaf het begin van het geheugen moet overslaan om de byte te vinden waarnaar hij op zoek is.
- Om toegang te krijgen tot de eerste byte moet het 0 bytes overslaan, dus het adres van de eerste byte is 0.
- Voor toegang tot de tweede byte moet 1 byte worden overgeslagen, dus het adres is 1.
- (enzovoorts… )
- Voor toegang tot de laatste byte slaat de CPU 1073741823 bytes over, dus het adres is 1073741823.
Nu moet je weten wat 32-bit eigenlijk betekent. Zoals ik eerder al zei, is het de grootte van een machinewoord.
Machinewoord is de hoeveelheid geheugen CPU-gebruik om nummers vast te houden (in RAM, cache of interne registers). 32-bits CPU gebruikt 32 bits (4 bytes) om getallen te bevatten. Geheugenadressen zijn ook getallen, dus op een 32-bits CPU bestaat het geheugenadres uit 32 bits.
Denk hier nu over na: als je één bit hebt, kun je er twee waarden op opslaan: 0 of 1. Voeg nog een bit toe en je hebt vier waarden: 0, 1, 2, 3. Op drie bits kun je acht waarden opslaan : 0, 1, 2 ... 6, 7. Dit is eigenlijk een binair systeem en het werkt zo:
Binair decimaal 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001 10 1010 11 1011 12 1100 13 1101 14 1110 15 1111
Het werkt precies zoals de gebruikelijke toevoeging, maar het maximale cijfer is 1, niet 9. Decimaal 0 is
0000
, dan voeg je er 1 toe en krijg je0001
, voeg er nog een toe en je hebt0010
. Wat hier gebeurde is als met een decimaal09
en er één toevoegen: je verandert 9 naar 0 en verhoogt het volgende cijfer.Uit het bovenstaande voorbeeld kunt u zien dat er altijd een maximale waarde is die u in een getal met een constant aantal bits kunt houden - omdat als alle bits 1 zijn en u probeert de waarde met 1 te verhogen, alle bits 0 worden, waardoor de aantal. Het wordt integer overflow genoemd en veroorzaakt veel onaangename problemen, zowel voor gebruikers als voor ontwikkelaars.
11111111 = 255 + 1 ----------- 100000000 = 0 (9 bits hier, dus 1 is bijgesneden)
- Voor 1 bit is de grootste waarde 1,
- 2 bits - 3,
- 3 bits - 7,
- 4 bits - 15
Het grootst mogelijke aantal is altijd 2 ^ N-1, waarbij N het aantal bits is. Zoals ik al eerder zei, is een geheugenadres een getal en heeft het ook een maximale waarde. Daarom is de grootte van het apparaatwoord ook een limiet voor het aantal beschikbare geheugenadressen - soms kan je CPU geen getallen verwerken die groot genoeg zijn om meer geheugen aan te kunnen..
Dus op 32 bits kun je nummers behouden van 0 tot 2 ^ 32-1, en dat is 4 294 967 295. Het is meer dan het beste adres in 1 GB RAM, dus in jouw specifieke geval zal de hoeveelheid RAM de beperkende factor zijn.
De RAM-limiet voor een 32-bits CPU is theoretisch 4 GB (2 ^ 32) en voor een 64-bits CPU is dit 16 EB (exabytes, 1 EB = 2 ^ 30 GB). Met andere woorden, een 64-bits CPU kan volledig internet adresseren ... 200 keer;) (geschat door WolframAlpha).
In real-life besturingssystemen kunnen 32-bits CPU's ongeveer 3 GiB RAM verwerken. Dat komt door de interne architectuur van het besturingssysteem: sommige adressen zijn gereserveerd voor andere doeleinden. U kunt meer lezen over deze zogenaamde barrière van 3 GB op Wikipedia. U kunt deze limiet opheffen met Physical Address Extension.
Over geheugenadressering gesproken, er zijn een paar dingen die ik moet noemen: virtueel geheugen, segmentatie en paging.
Virtueel geheugen
Zoals @Daniel R Hicks in een ander antwoord opmerkte, gebruiken besturingssystemen virtueel geheugen. Wat het betekent is dat applicaties eigenlijk niet werken op echte geheugenadressen, maar die door OS worden aangeboden.
Met deze techniek kan het besturingssysteem sommige gegevens uit het RAM verplaatsen naar een zogenaamd Pagefile (Windows) of Swap (* NIX). HDD is maar een paar keer langzamer dan RAM, maar het is geen ernstig probleem voor zelden gebruikte gegevens en het stelt OS in staat om applicaties meer RAM aan te bieden dan je daadwerkelijk hebt geïnstalleerd.
paging
Waar we tot nu toe over spraken, heet flat adresseringsschema.
Paging is een alternatief adresseringsschema dat toestaat om meer geheugen te adresseren dat u normaal gesproken zou kunnen hebben met één computermenu in een vlak model.
Stel je een boek voor dat gevuld is met woorden van 4 letters. Laten we zeggen dat er 1024 nummers op elke pagina staan. Om een nummer te adresseren, moet je twee dingen weten:
- Het aantal pagina's waarop dat woord wordt afgedrukt.
- Welk woord op die pagina is het woord dat je zoekt.
Dat is precies hoe moderne x86-CPU's omgaan met geheugen. Het is verdeeld in 4 KiB-pagina's (elk 1024 machinewoorden) en die pagina's hebben cijfers. (Eigenlijk kunnen pagina's ook 4 MiB groot of 2 MiB met PAE zijn). Als u de geheugencel wilt adresseren, hebt u het paginanummer en adres op die pagina nodig. Merk op dat op elke geheugencel precies een paar getallen wordt vermeld, dat is niet het geval voor segmentatie.
Segmentatie
Nou, deze is vrij gelijkaardig aan paging. Het werd gebruikt in Intel 8086, om maar een voorbeeld te noemen. Groepen adressen worden nu geheugensegmenten genoemd, geen pagina's. Het verschil is dat segmenten elkaar kunnen overlappen en dat ze elkaar vaak overlappen. Op 8086 waren bijvoorbeeld de meeste geheugencellen beschikbaar van 4096 verschillende segmenten.
Een voorbeeld:
Laten we zeggen dat we 8 bytes geheugen hebben, allemaal met nullen behalve de 4e byte die gelijk is aan 255.
Illustratie voor plat geheugenmodel:
_____ | 0 | | 0 | | 0 | | 255 | | 0 | | 0 | | 0 | | 0 | -----
Illustratie voor wisselgeheugen met 4-byte pagina's:
PAGE0 _____ | 0 | | 0 | | 0 | PAGE1 | 255 | _____ ----- | 0 | | 0 | | 0 | | 0 | -----
Illustratie voor gesegmenteerd geheugen met 4-bytesegmenten verschoven met 1:
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 | ----- ----- ----- -----
Zoals u kunt zien, kan de 4e byte op vier manieren worden geadresseerd: (adressering vanaf 0)
- Segment 0, offset 3
- Segment 1, offset 2
- Segment 2, offset 1
- Segment 3, offset 0
Het is altijd dezelfde geheugencel.
In real-life implementaties worden segmenten verschoven met meer dan 1 byte (voor 8086 was dit 16 bytes).
Het slechte aan segmentatie is dat het ingewikkeld is (maar ik denk dat je dat al weet;) Wat goed is, is dat je een aantal slimme technieken kunt gebruiken om modulaire programma's te maken.
U kunt bijvoorbeeld een module in een segment laden en vervolgens doen alsof het segment kleiner is dan het werkelijk is (net klein genoeg om de module vast te houden), kies vervolgens het eerste segment dat niet overlapt met dat pseudo-kleinere segment en laad het volgende module, enzovoort. Kortom, wat je op deze manier krijgt is pagina's van verschillende grootte.
Heb je iets toe te voegen aan de uitleg? Geluid uit in de reacties. Wilt u meer antwoorden van andere technisch onderlegde Stack Exchange-gebruikers lezen? Bekijk hier de volledige discussiethread.