Într-o zi este distractiv să te uiți la nivelul de suprafață al experienței de calcul, iar în alte zile este distractiv să te adânci chiar în funcționarea interioară. Astăzi aruncăm o privire asupra structurii memoriei computerului și cât de multe lucruri puteți împacheta într-un stick de memorie RAM.
Sesiunea de Întrebări și Răspunsuri de astăzi ne vine prin amabilitatea SuperUser - o subdiviziune a Stack Exchange, un grup de site-uri web de întrebări și răspunsuri bazat pe comunitate.
Intrebarea
Cititorul superutilizator Johan Smohan se confruntă cu modul în care tipul procesorului și dimensiunea memoriei funcționează împreună pentru a obține un număr total de adrese. El scrie:
Câte adrese de memorie putem obține cu un procesor pe 32 de biți și 1 GB RAM și câte cu un procesor pe 64 de biți?
Cred că este ceva de genul acesta:
1 GB de ram împărțit la 32 biți 4 biți (?) Pentru a obține numărul de adrese de memorie?
Am citit pe Wikipedia că 1 adresă de memorie are o lățime de 32 de biți sau 4 octeți (1 octet = 8 biți), comparativ cu un procesor de 64 de biți în care 1 adresă de memorie sau 1 număr întreg are 64 de biți lățime sau 8 octeți. Dar nici nu știu dacă am înțeles-o corect.
Acestea sunt genurile de întrebări care pot ține un geek curios pe timp de noapte. Câte adrese sunt disponibile sub fiecare dintre sistemele ipotetice ale lui Johan?
Răspunsul
Contribuitorul SuperUser Gronostaj oferă câteva informații despre modul în care RAM-ul este împărțit și utilizat:
Răspuns scurt: Numărul de adrese disponibile este egal cu cel mai mic dintre acestea:
- Dimensiunea memoriei în octeți
- Cel mai mare întreg nesemnat care poate fi salvat în cuvântul computer al procesorului
Răspuns lung și explicație pentru cele de mai sus:
Memoria constă din octeți (B). Fiecare octet este format din 8 biți (b).
1 B = 8 b1 GB RAM este de fapt 1 GiB (gibibyte, nu gigabyte). Diferența este:
1 GB = 10 ^ 9 B = 1 000 000 000 B 1 GiB = 2 ^ 30 B = 1 073 741 824 BFiecare octet de memorie are propria adresă, indiferent cât de mare este cuvântul mașină CPU. De exemplu. Procesorul Intel 8086 avea 16 biți și se ocupa de memorie pe octeți, la fel și procesorii moderni de 32 de biți și 64 de biți. Aceasta este cauza primei limite - nu puteți avea mai multe adrese decât octeți de memorie.
Adresa de memorie este doar un număr de octeți pe care CPU trebuie să-l omită de la începutul memoriei pentru a ajunge la cea pe care o caută.
- Pentru a accesa primul octet, acesta trebuie să omită 0 octeți, deci adresa primului octet este 0.
- Pentru a accesa al doilea octet trebuie să sări peste 1 octet, deci adresa sa este 1.
- (si asa mai departe…)
- Pentru a accesa ultimul octet, CPU omite 1073741823 octeți, deci adresa sa este 1073741823.
Acum trebuie să știți ce înseamnă de fapt 32 de biți. După cum am menționat anterior, este de mărimea unui cuvânt mașină.
Cuvântul mașină este cantitatea de memorie pe care CPU o utilizează pentru a păstra numerele (în memorie RAM, cache sau registre interne). CPU pe 32 de biți folosește 32 de biți (4 octeți) pentru a păstra numerele. Adresele de memorie sunt și ele numere, deci pe un procesor pe 32 de biți adresa de memorie este formată din 32 de biți.
Acum gândiți-vă la asta: dacă aveți un bit, puteți salva două valori pe el: 0 sau 1. Adăugați încă un bit și aveți patru valori: 0, 1, 2, 3. Pe trei biți, puteți salva opt valori : 0, 1, 2 ... 6, 7. Acesta este de fapt un sistem binar și funcționează așa:
Zecimal binar 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 1110 1111Funcționează exact ca adunarea obișnuită, dar cifra maximă este 1, nu 9. Zecimal 0 este
0000, apoi adăugați 1 și obțineți0001, adaugă încă o dată și ai0010. Ceea ce s-a întâmplat aici este ca și cum ai avea zecimal09și adăugând una: schimbați 9 la 0 și creșteți cifra următoare.Din exemplul de mai sus puteți vedea că există întotdeauna o valoare maximă pe care o puteți păstra într-un număr cu un număr constant de biți - pentru că atunci când toți biții sunt 1 și încercați să măriți valoarea cu 1, toți biții vor deveni 0, rupând astfel număr. Se numește depășire de număr întreg și provoacă multe probleme neplăcute, atât pentru utilizatori, cât și pentru dezvoltatori.
11111111 = 255 + 1 ----------- 100000000 = 0 (9 biți aici, deci 1 este tăiat)
- Pentru 1 bit cea mai mare valoare este 1,
- 2 biți - 3,
- 3 biți - 7,
- 4 biți - 15
Cel mai mare număr posibil este întotdeauna 2 ^ N-1, unde N este numărul de biți. După cum am mai spus, o adresă de memorie este un număr și are și o valoare maximă. De aceea, dimensiunea word machine este, de asemenea, o limită pentru numărul de adrese de memorie disponibile - uneori procesorul dvs. nu poate procesa numere suficient de mari pentru a adresa mai multă memorie.
Deci, pe 32 de biți puteți păstra numerele de la 0 la 2 ^ 32-1, și asta înseamnă 4 294 967 295. Este mai mult decât cea mai bună adresă din 1 GB RAM, deci, în cazul dvs. specific, cantitatea de RAM va fi factorul limitativ.
Limita RAM pentru CPU pe 32 de biți este teoretic de 4 GB (2 ^ 32), iar pentru CPU pe 64 de biți este de 16 EB (exabytes, 1 EB = 2 ^ 30 GB). Cu alte cuvinte, procesorul pe 64 de biți s-ar putea adresa întregului Internet ... de 200 de ori;) (estimat de WolframAlpha ).
Cu toate acestea, în sistemele de operare din viața reală CPU-urile pe 32 de biți pot adresa aproximativ 3 GiB de RAM. Acest lucru se datorează arhitecturii interne a sistemului de operare - unele adrese sunt rezervate în alte scopuri. Puteți citi mai multe despre acest așa-numit 3 GB barieră pe Wikipedia . Puteți ridica această limită cu Extensie de adresă fizică .
Vorbind despre adresarea memoriei, sunt câteva lucruri pe care ar trebui să le menționez: virtual memory , segmentare și paginare .
Virtual memory
După cum a subliniat @Daniel R Hicks într-un alt răspuns, sistemele de operare folosesc memoria virtuală. Ceea ce înseamnă este că aplicațiile nu funcționează de fapt pe adrese de memorie reale, ci pe cele furnizate de sistemul de operare.
Această tehnică permite sistemului de operare să mute unele date din RAM pe așa-numitul Pagefile (Windows) sau Swap (* NIX). HDD-ul este cu câteva magnitudini mai lent decât memoria RAM, dar nu este o problemă serioasă pentru datele accesate rar și permite sistemului de operare să ofere aplicațiilor mai multă memorie RAM decât ai instalat de fapt.
Paginarea
Ceea ce vorbeam până acum se numește schemă de adresare plană.
Paginarea este o schemă de adresare alternativă care permite adresarea mai multor memorii pe care le-ați putea în mod normal cu un cuvânt automat în modelul plat.
Imaginați-vă o carte plină cu cuvinte din 4 litere. Să presupunem că există 1024 de numere pe fiecare pagină. Pentru a adresa un număr, trebuie să știți două lucruri:
- Numărul de pagină pe care este tipărit acel cuvânt.
- Ce cuvânt din pagina respectivă este cel pe care îl căutați.
Acum este exact modul în care procesorii moderni x86 gestionează memoria. Este împărțit în 4 pagini KiB (câte 1024 de cuvinte automate fiecare) și acele pagini au numere. (de fapt, paginile pot fi de asemenea 4 MiB mari sau 2 MiB cu PAE ). Când doriți să adresați celula de memorie, aveți nevoie de numărul și adresa paginii din acea pagină. Rețineți că fiecare celulă de memorie face trimitere cu exact o pereche de numere, care nu va fi cazul segmentării.
Segmentare
Ei bine, acesta este destul de similar cu paginarea. A fost folosit în Intel 8086, doar pentru a numi un exemplu. Grupurile de adrese sunt acum numite segmente de memorie, nu pagini. Diferența este că segmentele se pot suprapune și se suprapun foarte mult. De exemplu, pe 8086 majoritatea celulelor de memorie erau disponibile din 4096 segmente diferite.
Un exemplu:
Să presupunem că avem 8 octeți de memorie, toate conținând zerouri, cu excepția celui de-al 4-lea octet care este egal cu 255.
Ilustrație pentru modelul de memorie plană:
_____ | 0 | | 0 | | 0 | | 255 | | 0 | | 0 | | 0 | | 0 | -----Ilustrație pentru memoria paginată cu pagini de 4 octeți:
PAGINA0 _____ | 0 | | 0 | | 0 | PAGINA 1 | 255 | _____ ----- | 0 | | 0 | | 0 | | 0 | -----Ilustrație pentru memoria segmentată cu segmente de 4 octeți deplasate cu 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 | ----- ----- ----- -----După cum puteți vedea, al 4-lea octet poate fi adresat în patru moduri: (adresarea de la 0)
- Segmentul 0, offsetul 3
- Segmentul 1, compensarea 2
- Segmentul 2, compensarea 1
- Segmentul 3, compensarea 0
Este întotdeauna aceeași celulă de memorie.
În implementările din viața reală, segmentele sunt deplasate cu mai mult de 1 octet (pentru 8086 erau 16 octeți).
Ce este rău în segmentare este că este complicat (dar cred că știți deja acest lucru;) Ce este bine, este că puteți utiliza unele tehnici inteligente pentru a crea programe modulare.
De exemplu, puteți încărca un modul într-un segment, apoi prefaceți-vă că segmentul este mai mic decât este cu adevărat (doar suficient de mic pentru a ține modulul), apoi alegeți primul segment care nu se suprapune cu cel pseudo-mai mic și încărcați următorul modul, și așa mai departe. Practic, ceea ce obțineți în acest fel sunt pagini cu dimensiuni variabile.
Aveți ceva de adăugat la explicație? Sună în comentarii. Doriți să citiți mai multe răspunsuri de la alți utilizatori ai Stack Exchange? Consultați aici firul complet de discuție .