20Aug
Soms 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 kunt inpakken in een RAM-geheugen.
De vraag van vandaag &Antwoord sessie komt naar ons met dank aan SuperUser-een onderverdeling van Stack Exchange, een community-gestuurde groepering 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 ongeveer zoiets is:
1GB ram gedeeld door 32 bits 4 bits( ?) Om het aantal geheugenadressen te krijgen?
Ik lees op Wikipedia dat 1 geheugenadres 32 bits breed is of 4 octetten( 1 octet = 8 bits), vergeleken met een 64 bit-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 de kleinste daarvan:
- Geheugengrootte in bytes
- Grootste niet-ondertekende gehele getal dat kan worden opgeslagenin CPU's machinewoord
Lang antwoord en verklaring van het bovenstaande:
Geheugen bestaat uit bytes( B).Elke byte bestaat uit 8 bits( b).
1 B = 8 b1 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 BElke 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.
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.
- Voor toegang tot de eerste byte moet het 0 bytes overslaan, dus het adres van de eerste byte is 0.
- Om toegang te krijgen tot de tweede byte moet het 1 byte overslaan, dus het adres is 1.
- ( enzovoort)
- Voor toegang tot delaatste byte, CPU slaat 1073741823 bytes over, dus het adres is 1073741823.
Nu moet je weten wat 32-bits 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 nummers 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 opslaanwaarden: 0, 1, 2. .. 6, 7. Dit is eigenlijk een binair systeem en het werkt als volgt:
Binary Decimal 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001 10 1010 111011 12 1100 13 1101 14 1110 15 1111Het werkt precies zoals de gebruikelijke toevoeging, maar het maximale cijfer is 1, niet 9. Decimaal 0 is 0000, dan voegt u 1 toe en krijgt u 0001, voegt u er een toe en heeft u 0010. WatHier is het alsof je decimale 09 hebt en er één toevoegt: je verandert 9 naar 0 en verhoogt het volgende cijfer.
Uit het bovenstaande voorbeeld kun je zien dat er altijd een maximale waarde is die je kunt behouden in een getal met een constant aantal bits - omdat als alle bits 1 zijn en je probeert de waarde met 1 te verhogen, alle bits 0 worden en dus brekenhet nummer. 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 uw CPU geen getallen verwerken die groot genoeg zijn om meer geheugen aan te kunnen.
Dus met 32 bits kun je nummers van 0 tot 2 ^ 32-1 behouden, 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 het hele internet adresseren. .. 200 keer;)( geschat door WolframAlpha).
In echte 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 een beetje langzamer dan RAM, maar het is geen serieus probleem voor zelden gebruikte gegevens en het stelt OS in staat om applicaties meer RAM te bieden dan je eigenlijk hebt geïnstalleerd.
paging
Waar we tot nu toe over spraken, heet flat adresseringsschema.
Paging is een alternatief adresseringsschema waarmee u meer geheugen kunt adresseren dat u normaal gesproken met één computermenu in een vlak model zou kunnen gebruiken.
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 u twee dingen weten:
- Het aantal pagina's waarop dat woord wordt afgedrukt.
- Welk woord op die pagina is het woord dat u 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 elke geheugencel wordt aangeduid met exact één paar cijfers, dat is niet het geval voor segmentatie.
Segmentation
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 uit 4096 verschillende segmenten.
Een voorbeeld:
Laten we zeggen dat we 8 bytes geheugen hebben, allemaal met nullen behalve 4e byte, wat gelijk is aan 255.
Afbeelding voor flat-geheugenmodel:
_____ |0 ||0 ||0 ||255 ||0 ||0 ||0 ||0 |-----Illustratie voor wisselgeheugen met 4-byte pagina's:
PAGO0 _____ |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 je 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).
Wat jammer is 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 dan doen alsof het segment kleiner is dan het werkelijk is( net klein genoeg om de module vast te houden), kies dan het eerste segment dat niet overlapt met dat pseudo-kleinere segment en laadvolgende module, enzovoort. Kortom, wat je op deze manier krijgt is pagina's van variabele grootte.
Heeft u iets toe te voegen aan de uitleg? Geluid uit in de opmerkingen. Wilt u meer antwoorden van andere technisch onderlegde Stack Exchange-gebruikers lezen? Bekijk de volledige discussiethread hier.