En dag er det sjovt at se på overfladeniveauet af computeroplevelsen, og andre dage er det sjovt at dykke ned i det indre arbejde. I dag ser vi på strukturen i computerhukommelsen, og hvor mange ting du kan pakke i en RAM-nøgle.
Dagens spørgsmål og svar-session kommer til os med tilladelse fra SuperUser - en underinddeling af Stack Exchange, en community-driven gruppe af Q&A websteder.
Spørgsmålet
SuperUser-læser Johan Smohan kæmper med, hvordan processortype og hukommelsesstørrelse fungerer sammen for at give et samlet antal adresser. Han skriver:
Hvor mange hukommelsesadresser kan vi få med en 32-bit processor og 1 GB RAM, og hvor mange med en 64-bit processor?
Jeg tror, det er sådan noget:
1 GB ram divideret med enten 32 bits 4 bits (?) For at få antallet af hukommelsesadresser?
Jeg læste på Wikipedia, at 1 hukommelsesadresser er 32 bits brede eller 4 oktetter (1 oktet = 8 bit) sammenlignet med en 64 bit processor, hvor 1 hukommelsesadresser eller 1 heltal er 64 bit bred eller 8 oktetter. Men ved ikke, om jeg heller ikke forstod det korrekt.
Dette er de slags spørgsmål, der kan holde en nysgerrig nørd op om natten. Hvor mange adresser er tilgængelige under hvert af Johans hypotetiske systemer?
Svaret
SuperUser-bidragyder Gronostaj giver noget indblik i, hvordan RAM-enheden er opdelt og brugt:
Kort svar: Antallet af tilgængelige adresser er lig med den mindste af disse:
- Hukommelsesstørrelse i byte
- Største usignerede heltal, der kan gemmes i CPU's maskinord
Langt svar og forklaring på ovenstående:
Hukommelsen består af bytes (B). Hver byte består af 8 bit (b).
1 B = 8 b1 GB RAM er faktisk 1 GiB (gibibyte, ikke gigabyte). Forskellen er:
1 GB = 10 ^ 9 B = 1 000 000 000 B 1 GiB = 2 ^ 30 B = 1073 741824 BHver hukommelsesbyte har sin egen adresse, uanset hvor stort CPU-maskinordet er. F.eks. Intel 8086 CPU var 16-bit, og den adresserede hukommelse bytes, det samme gør moderne 32-bit og 64-bit CPU'er. Det er årsagen til den første grænse - du kan ikke have flere adresser end hukommelsesbyte.
Hukommelsesadresse er kun et antal byte, som CPU'en skal springe over fra begyndelsen af hukommelsen for at komme til den, den leder efter.
- For at få adgang til den første byte skal den springe over 0 byte, så den første bytes adresse er 0.
- For at få adgang til den anden byte skal den springe 1 byte over, så dens adresse er 1.
- (og så videre…)
- For at få adgang til den sidste byte springer CPU over 1073741823 bytes, så dens adresse er 1073741823.
Nu skal du vide, hvad 32-bit faktisk betyder. Som jeg nævnte før, er det størrelsen på et maskinord.
Maskinord er den mængde hukommelse, CPU bruger til at holde numre (i RAM, cache eller interne registre). 32-bit CPU bruger 32 bits (4 bytes) til at holde numre. Hukommelsesadresser er også tal, så på en 32-bit CPU består hukommelsesadressen af 32 bit.
Tænk nu over dette: hvis du har en bit, kan du gemme to værdier på den: 0 eller 1. Tilføj en bit mere, og du har fire værdier: 0, 1, 2, 3. På tre bits kan du gemme otte værdier : 0, 1, 2… 6, 7. Dette er faktisk et binært system, og det fungerer sådan:
Binær decimal 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 1111Det fungerer nøjagtigt som almindelig tilføjelse, men det maksimale ciffer er 1, ikke 9. Decimal 0 er
0000, så tilføjer du 1 og får0001, tilføj en igen, og du har0010. Hvad der skete her er som at have decimal09og tilføje en: du ændrer 9 til 0 og øger det næste ciffer.Fra eksemplet ovenfor kan du se, at der altid er en maksimumsværdi, du kan gemme i et tal med konstant antal bits - for når alle bits er 1, og du prøver at øge værdien med 1, bliver alle bits 0 og derved bryder nummer. Det kaldes heltalsoverløb og forårsager mange ubehagelige problemer, både for brugere og udviklere.
11111111 = 255 + 1 ----------- 100000000 = 0 (9 bits her, så 1 er trimmet)
- For 1 bit er den største værdi 1,
- 2 bits - 3,
- 3 bits - 7,
- 4 bits - 15
Det størst mulige antal er altid 2 ^ N-1, hvor N er antallet af bits. Som jeg sagde før, er en hukommelsesadresse et tal, og det har også en maksimal værdi. Derfor er maskinordets størrelse også en grænse for antallet af tilgængelige hukommelsesadresser - nogle gange kan din CPU bare ikke behandle numre, der er store nok til at adressere mere hukommelse.
Så på 32 bits kan du holde numre fra 0 til 2 ^ 32-1, og det er 4 294 967 295. Det er mere end den største adresse i 1 GB RAM, så i dit specifikke tilfælde vil RAM være den begrænsende faktor.
RAM-grænsen for 32-bit CPU er teoretisk 4 GB (2 ^ 32) og for 64-bit CPU er det 16 EB (exabyte, 1 EB = 2 ^ 30 GB). Med andre ord kunne 64-bit CPU adressere hele Internettet ... 200 gange;) (estimeret af WolframAlpha ).
Imidlertid kan 32-bit CPU'er i virkelige operativsystemer adressere omkring 3 GiB RAM. Det skyldes operativsystemets interne arkitektur - nogle adresser er reserveret til andre formål. Du kan læse mere om denne såkaldte 3 GB barriere på Wikipedia . Du kan hæve denne grænse med Udvidelse af fysisk adresse .
Når vi taler om hukommelsesadressering, er der få ting, jeg skal nævne: virtuel hukommelse , segmentering og personsøgning .
Virtuel hukommelse
Som @Daniel R Hicks påpegede i et andet svar, bruger operativsystemer virtuel hukommelse. Hvad det betyder er, at applikationer faktisk ikke fungerer på ægte hukommelsesadresser, men dem, der leveres af OS.
Denne teknik gør det muligt for operativsystemet at flytte nogle data fra RAM til en såkaldt Pagefile (Windows) eller Swap (* NIX). HDD er få størrelser langsommere end RAM, men det er ikke et alvorligt problem for sjældent tilgængelige data, og det giver OS mulighed for at give applikationer mere RAM, end du faktisk har installeret.
Personsøgning
Det, vi hidtil talte om, kaldes flad adresseringsordning.
Personsøgning er et alternativt adresseringsskema, der giver mulighed for at adressere mere hukommelse, som du normalt kunne med et maskineord i flad model.
Forestil dig en bog fyldt med ord på 4 bogstaver. Lad os sige, at der er 1024 numre på hver side. For at adressere et nummer skal du vide to ting:
- Antallet af side, hvor dette ord er udskrevet.
- Hvilket ord på den side er det, du leder efter.
Nu er det nøjagtigt, hvordan moderne x86-CPU'er håndterer hukommelse. Den er opdelt i 4 KiB-sider (hver 1024 maskineord), og disse sider har tal. (faktisk kan sider også være 4 MiB store eller 2 MiB med PAE ). Når du vil adressere hukommelsescelle, skal du bruge sidenummeret og adressen på den side. Bemærk, at hver hukommelsescelle henvises til med nøjagtigt et par tal, hvilket ikke er tilfældet for segmentering.
Segmentering
Nå, denne ligner meget personsøgning. Det blev brugt i Intel 8086, bare for at nævne et eksempel. Grupper af adresser kaldes nu hukommelsessegmenter, ikke sider. Forskellen er, at segmenter kan overlappe hinanden, og de overlapper meget. For eksempel på 8086 var de fleste hukommelsesceller tilgængelige fra 4096 forskellige segmenter.
Et eksempel:
Lad os sige, at vi har 8 byte hukommelse, der alle indeholder nuller undtagen 4. byte, der er lig med 255.
Illustration til flad hukommelsesmodel:
_____ | 0 | | 0 | | 0 | | 255 | | 0 | | 0 | | 0 | | 0 | -----Illustration til sidehukommelse med 4-byte sider:
SIDE0 _____ | 0 | | 0 | | 0 | SIDE 1 | 255 | _____ ----- | 0 | | 0 | | 0 | | 0 | -----Illustration til segmenteret hukommelse med 4-bytesegmenter forskudt med 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 | ----- ----- ----- -----Som du kan se, kan 4. byte adresseres på fire måder: (adressering fra 0)
- Segment 0, forskudt 3
- Segment 1, forskydning 2
- Segment 2, forskydning 1
- Segment 3, forskydning 0
Det er altid den samme hukommelsescelle.
I virkelige implementeringer skiftes segmenter med mere end 1 byte (for 8086 var det 16 byte).
Hvad der er dårligt ved segmentering er, at det er kompliceret (men jeg tror, du ved det allerede;) Hvad der er godt, er at du kan bruge nogle kloge teknikker til at oprette modulære programmer.
For eksempel kan du indlæse nogle moduler i et segment og derefter lade som om segmentet er mindre end det virkelig er (bare lille nok til at holde modulet) og derefter vælge det første segment, der ikke overlapper den pseudo-mindre og indlæse næste modul osv. Dybest set, hvad du får på denne måde er sider med variabel størrelse.
Har du noget at tilføje til forklaringen? Lyder i kommentarerne. Vil du læse flere svar fra andre teknisk kyndige Stack Exchange-brugere? Tjek den fulde diskussionstråd her .