Hvor mange hukommelsesadresser kan RAM'en i min computer holde?
I nogle dage er det sjovt at se på overfladeniveauet af computerværelsen, og i andre dage er det sjovt at dykke lige ind i det indre arbejde. I dag tager vi et kig på strukturen i computerens hukommelse og hvor mange ting du kan pakke ind i en stok med RAM.
Dagens Spørgsmål & Svar session kommer til os med venlig hilsen af SuperUser-en underafdeling af Stack Exchange, en community-driven gruppe af Q & A-websteder.
Spørgsmålet
SuperUser-læser Johan Smohan bryder sig om, hvordan processortype og hukommelsesstørrelse virker sammen for at give et samlet antal adresser. Han skriver:
Hvor mange hukommelsesadresser kan vi få med en 32-bit processor og 1GB RAM og hvor mange med en 64-bit processor?
Jeg synes, at det er sådan noget:
1 GB ram delt med enten 32 bit 4 bits (?) For at hente antallet af hukommelsesadresser?
Jeg læser på Wikipedia, at 1 hukommelsesadresse er 32 bit bredt eller 4 oktetter (1 octet = 8 bits), sammenlignet med en 64 bit processor hvor 1 hukommelse adresser eller 1 heltal er 64 bit bred eller 8 oktetter. Men ved ikke, om jeg også forstod det korrekt.
Det er de slags spørgsmål, der kan holde en nysgerrig geek om natten. Hvor mange adresser er tilgængelige under hvert af Johans hypotetiske systemer?
Svaret
SuperUser bidragyder Gronostaj giver nogle indsigt i, hvordan RAM er opdelt og udnyttet:
Kort svar: Antallet af tilgængelige adresser er lig med de mindre af dem:
- Hukommelsesstørrelse i byte
- Største usignerede heltal, der kan gemmes i CPUs maskinord
Langt svar og forklaring af ovenstående:
Hukommelsen består af bytes (B). Hver byte består af 8 bit (b).
1 B = 8 b
1 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 = 1 073 741 824 B
Hver byte af hukommelse har sin egen adresse, uanset hvor stor CPU-maskinordet er. F.eks. Intel 8086 CPU var 16-bit, og den adresserede hukommelse af bytes, så 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 hukommelsesbytes.
Hukommelsesadresse er blot et antal bytes, som CPU'en skal springe 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å første bytes adresse er 0.
- For at få adgang til den anden byte skal den hoppe over 1 byte, så adressen er 1.
- (og så videre… )
- For at få adgang til den sidste byte springer CPU 1073741823 bytes, så adressen er 1073741823.
Nu skal du vide, hvad 32-bit rent faktisk betyder. Som jeg nævnte før, er det størrelsen af et maskinord.
Maskinord er mængden af hukommelses CPU bruger til at holde numre (i RAM, cache eller interne registre). 32-bit CPU bruger 32 bit (4 bytes) til at holde tal. Hukommelsesadresser er også tal, så på en 32-bit CPU indeholder hukommelsesadressen 32 bits.
Tænk nu på dette: Hvis du har en smule, kan du gemme to værdier på den: 0 eller 1. Tilføj en yderligere bit, 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 virker sådan:
Binært decimalt 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
Det virker præcis som sædvanlig tilføjelse, men det maksimale ciffer er 1, ikke 9. Desimal 0 er
0000
, så tilføjer du 1 og får0001
, tilføj en endnu en gang, og du har0010
. Hvad der sker her er ligesom at have decimal09
og tilføjer en: Du ændrer 9 til 0 og øger næste ciffer.I eksemplet ovenfor kan du se, at der altid er en maksimumsværdi, du kan holde i et tal med konstant antal bits - fordi når alle bit er 1, og du forsøger at øge værdien med 1, bliver alle bits 0, og dermed brydes de nummer. Det kaldes heltal overlø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ørste mulige tal 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. Sommetider kan din CPU bare ikke behandle tal, der er store nok til at adressere mere hukommelse.
Så på 32 bit kan du holde tal 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 mængden af 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 (exabytes, 1 EB = 2 ^ 30 GB). Med andre ord, 64-bit CPU kunne adressere hele internettet ... 200 gange;) (estimeret af WolframAlpha).
I virkelige operativsystemer kan 32-bit CPU'er imidlertid adressere omkring 3 GiB RAM. Det skyldes operativsystemets interne arkitektur - nogle adresser er forbeholdt andre formål. Du kan læse mere om denne såkaldte 3 GB barriere på Wikipedia. Du kan løfte denne grænse med Fysisk adresseudvidelse.
Tale om hukommelse adressering, er der få ting, jeg bør nævne: virtuel hukommelse, segmentering og personsøgning.
Virtual hukommelse
Som @Daniel R Hicks påpeget i et andet svar bruger OS'er virtuel hukommelse. Hvad det betyder er, at applikationer rent faktisk ikke fungerer på rigtige 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 levere applikationer mere RAM end du faktisk har installeret.
Paging
Hvad vi snakkede om hidtil kaldes flad adresseringsordning.
Personsøgning er en alternativ adresseringsordning, der gør det muligt at adressere mere hukommelse, som du normalt kunne med et maskinord i flad model.
Forestil dig en bog fyldt med 4 bogstaver. Lad os sige, at der er 1024 numre på hver side. For at adressere et nummer skal du kende to ting:
- Antallet af side, som det pågældende ord er trykt på.
- Hvilket ord på den side er det du leder efter.
Nu er det præcis, hvordan moderne x86-CPU'er håndterer hukommelsen. Det er opdelt i 4 KiB sider (1024 maskinord hver) og disse sider har tal. (faktisk sider kan 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 pågældende side. Bemærk, at hver hukommelsescelle refereres med nøjagtigt et par tal, det vil ikke være tilfældet for segmentering.
Segmentering
Nå, det samme ligner paging. Det blev brugt i Intel 8086, bare for at nævne et eksempel. Grupper af adresser hedder nu hukommelsessegmenter, ikke sider. Forskellen er, at segmenter kan overlappe hinanden, og de overlap meget. For eksempel var i 8086 de fleste hukommelsesceller tilgængelige fra 4096 forskellige segmenter.
Et eksempel:
Lad os sige, at vi har 8 bytes hukommelse, alle med nuler bortset fra 4. byte, som er lig med 255.
Illustration til flad hukommelsesmodel:
_____ | 0 | | 0 | | 0 | | 255 | | 0 | | 0 | | 0 | | 0 | -----
Illustration til paged hukommelse med 4-byte sider:
PAGE0 _____ | 0 | | 0 | | 0 | SIDE1 | 255 | _____ ----- | 0 | | 0 | | 0 | | 0 | -----
Illustration til segmenteret hukommelse med 4-bytesegmenter skiftet 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, forskydning 3
- Segment 1, forskydning 2
- Segment 2, forskydning 1
- Segment 3, forskydning 0
Det er altid den samme hukommelsescelle.
I virkeligheden implementeres segmenter med mere end 1 byte (i 8086 var det 16 byte).
Hvad der er dårligt om segmentering er, at det er kompliceret (men jeg tror du allerede ved det;) Hvad er godt, er at du kan bruge nogle kloge teknikker til at oprette modulære programmer.
Du kan f.eks. Indlæse et modul i et segment og lade ud som om segmentet er mindre end det egentlig er (bare lille nok til at holde modulet), og vælg derefter det første segment, der ikke overlapper den pågældende pseudo-mindre modul, og så videre. Dybest set, hvad du får på denne måde er sider med variabel størrelse.
Har du noget at tilføje til forklaringen? Lyde af i kommentarerne. Vil du læse flere svar fra andre tech-savvy Stack Exchange brugere? Tjek den fulde diskussionstråd her.