Ile adresów pamięci może pomieścić pamięć RAM w moim komputerze?
W pewnym momencie fajnie jest spojrzeć na poziom powierzchni komputera, a innym razem fajnie jest zagłębić się w wewnętrzne działania. Dzisiaj przyjrzymy się strukturze pamięci komputera i ilości rzeczy, które można spakować do pamięci RAM.
Dzisiejsza sesja pytań i odpowiedzi przychodzi do nas dzięki uprzejmości SuperUser - poddziału Stack Exchange, opartego na społecznościach grupowania witryn z pytaniami i odpowiedziami.
Pytanie
Czytnik SuperUser Johan Smohan zmaga się z tym, jak typ procesora i rozmiar pamięci współpracują ze sobą, aby uzyskać całkowitą liczbę adresów. On pisze:
Ile adresów pamięci możemy uzyskać za pomocą 32-bitowego procesora i 1 GB pamięci RAM, a ile z 64-bitowego procesora?
Myślę, że to coś takiego:
1 GB pamięci RAM podzielone przez 32 bity 4-bitowe (?), Aby uzyskać liczbę adresów pamięci?
Czytałem na Wikipedii, że 1 adres pamięci ma szerokość 32 bitów lub 4 oktety (1 oktet = 8 bitów), w porównaniu z procesorem 64-bitowym, w którym 1 adres pamięci lub 1 liczba całkowita ma szerokość 64 bitów lub 8 oktetów. Ale nie wiem, czy zrozumiałem to poprawnie.
Są to pytania, które mogą utrzymać ciekawość w nocy. Ile adresów jest dostępnych pod każdym z hipotetycznych systemów Johana?
Odpowiedź
Pomocnik SuperUser Gronostaj oferuje wgląd w sposób, w jaki pamięć RAM jest dzielona i wykorzystywana:
Krótka odpowiedź: Liczba dostępnych adresów jest równa mniejszej z nich:
- Rozmiar pamięci w bajtach
- Największa bez znaku liczba całkowita, którą można zapisać w słowie maszynowym procesora
Długa odpowiedź i wyjaśnienie powyższego:
Pamięć składa się z bajtów (B). Każdy bajt składa się z 8 bitów (b).
1 B = 8 b
1 GB pamięci RAM to 1 GiB (gibibyte, nie gigabajt). Różnica polega na:
1 GB = 10 ^ 9 B = 1 000 000 000 B 1 GiB = 2 ^ 30 B = 1 073 741 824 B
Każdy bajt pamięci ma swój własny adres, bez względu na to, jak duże jest słowo maszyny CPU. Na przykład. Procesor Intel 8086 był 16-bitowy i adresował pamięć po bajtach, podobnie jak nowoczesne 32-bitowe i 64-bitowe procesory. To jest przyczyna pierwszego limitu - nie możesz mieć więcej adresów niż bajty pamięci.
Adres pamięci to tylko kilka bajtów, które CPU musi przeskoczyć od początku pamięci, aby dostać się do tego, którego szuka.
- Aby uzyskać dostęp do pierwszego bajtu, należy pominąć 0 bajtów, więc adres pierwszego bajtu to 0.
- Aby uzyskać dostęp do drugiego bajtu, należy pominąć 1 bajt, więc jego adres to 1.
- (i tak dalej… )
- Aby uzyskać dostęp do ostatniego bajtu, procesor pomija 1073741823 bajtów, więc jego adres to 1073741823.
Teraz musisz wiedzieć, co właściwie oznacza 32-bit. Jak wspomniałem wcześniej, jest to rozmiar słowa maszynowego.
Słowo maszynowe to ilość pamięci używanej przez CPU do przechowywania liczb (w pamięci RAM, pamięci podręcznej lub rejestrach wewnętrznych). 32-bitowy procesor wykorzystuje 32 bity (4 bajty) do przechowywania liczb. Adresy pamięci również są liczbami, więc na 32-bitowym procesorze adres pamięci składa się z 32 bitów.
Pomyśl o tym: jeśli masz jeden bit, możesz zapisać dwie wartości: 0 lub 1. Dodaj jeszcze jeden bit i masz cztery wartości: 0, 1, 2, 3. Na trzech bitach możesz zapisać osiem wartości : 0, 1, 2 ... 6, 7. Jest to właściwie system binarny i działa tak:
Binary 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 1111
Działa dokładnie tak, jak zwykle, ale maksymalna cyfra to 1, a nie 9. Dziesiętny 0 to
0000
, następnie dodajesz 1 i dostajesz0001
, dodaj jeszcze raz i już masz0010
. To, co się tutaj dzieje, jest jak z dziesiętnym09
i dodanie: zmieniasz 9 na 0 i zwiększasz kolejną cyfrę.Z powyższego przykładu widać, że zawsze istnieje maksymalna wartość, jaką można zachować w liczbie o stałej liczbie bitów - ponieważ gdy wszystkie bity wynoszą 1, a spróbujesz zwiększyć wartość o 1, wszystkie bity staną się 0, numer. Nazywa się to przepełnieniem całkowitym i powoduje wiele nieprzyjemnych problemów, zarówno dla użytkowników, jak i programistów.
11111111 = 255 + 1 ----------- 100000000 = 0 (tutaj 9 bitów, więc 1 jest przycięte)
- Dla 1-bitowej największą wartością jest 1,
- 2 bity - 3,
- 3 bity - 7,
- 4 bity - 15
Największą możliwą liczbą jest zawsze 2 ^ N-1, gdzie N to liczba bitów. Jak już wcześniej wspomniałem, adres pamięci jest liczbą i ma również maksymalną wartość. Dlatego wielkość słowa maszynowego jest również limitem liczby dostępnych adresów pamięci - czasami twój procesor po prostu nie może przetwarzać liczb wystarczająco dużych, aby adresować więcej pamięci.
Tak więc na 32 bitach można zachować liczby od 0 do 2 ^ 32-1, a to 4 294 967 295. To więcej niż największy adres w 1 GB pamięci RAM, więc w konkretnym przypadku ilość pamięci RAM będzie czynnikiem ograniczającym.
Limit pamięci RAM dla 32-bitowego procesora wynosi teoretycznie 4 GB (2 ^ 32), a dla 64-bitowego procesora 16 EB (exabajty, 1 EB = 2 ^ 30 GB). Innymi słowy, 64-bitowy procesor może adresować cały Internet ... 200 razy;) (szacowany przez WolframAlpha).
Jednak w rzeczywistych systemach operacyjnych 32-bitowe procesory mogą adresować około 3 GiB pamięci RAM. Wynika to z wewnętrznej architektury systemu operacyjnego - niektóre adresy są zarezerwowane dla innych celów. Możesz przeczytać więcej o tej tak zwanej barierze 3 GB na Wikipedii. Możesz podnieść ten limit za pomocą rozszerzenia adresu fizycznego.
Mówiąc o adresowaniu pamięci, jest kilka rzeczy, o których powinienem wspomnieć: pamięć wirtualna, segmentacja i przywoływanie.
Pamięć wirtualna
Jak @Daniel R Hicks wskazał w innej odpowiedzi, systemy operacyjne używają pamięci wirtualnej. Oznacza to, że aplikacje faktycznie nie działają na rzeczywistych adresach pamięci, ale te dostarczane przez system operacyjny.
Ta technika pozwala systemowi operacyjnemu przenieść niektóre dane z pamięci RAM do tzw. Pagefile (Windows) lub Swap (* NIX). HDD ma niewiele wolniej niż pamięć RAM, ale nie jest to poważny problem w przypadku rzadko uzyskiwanych danych i pozwala systemowi operacyjnemu na dostarczanie aplikacji więcej pamięci RAM, niż faktycznie zainstalowano.
Stronicowanie
To, o czym mówiliśmy do tej pory, nazywa się płaskim systemem adresowania.
Paging jest alternatywnym schematem adresowania, który pozwala na adresowanie większej ilości pamięci, jaką normalnie można uzyskać za pomocą jednego słowa maszynowego w modelu płaskim.
Wyobraź sobie książkę wypełnioną 4-literowymi słowami. Załóżmy, że na każdej stronie znajduje się 1024 numery. Aby zaadresować numer, musisz znać dwie rzeczy:
- Liczba stron, na których drukowane jest to słowo.
- Które słowo na tej stronie jest tym, którego szukasz.
Właśnie tak wygląda współczesne procesory x86 obsługujące pamięć. Jest on podzielony na 4 strony KiB (1024 słowa maszynowe każda) i te strony mają numery. (w rzeczywistości strony mogą być również 4 MiB duże lub 2 MiB z PAE). Jeśli chcesz adresować komórki pamięci, potrzebujesz numeru strony i adresu na tej stronie. Zauważ, że do każdej komórki pamięci odwołuje się dokładnie jedna para liczb, która nie będzie miała miejsca w przypadku segmentacji.
Segmentacja
Ta jest podobna do stronicowania. Został użyty w Intel 8086, żeby wymienić tylko jeden przykład. Grupy adresów są teraz nazywane segmentami pamięci, a nie stronami. Różnica polega na tym, że segmenty mogą się nakładać i nakładają się bardzo często. Na przykład w 8086 większość komórek pamięci była dostępna z 4096 różnych segmentów.
Przykład:
Powiedzmy, że mamy 8 bajtów pamięci, wszystkie utrzymują zera oprócz czwartego bajtu, który jest równy 255.
Ilustracja do płaskiego modelu pamięci:
_____ | 0 | | 0 | | 0 | | 255 | | 0 | | 0 | | 0 | | 0 | -----
Ilustracja do pamięci stronicowanej z 4-bajtowymi stronami:
PAGE0 _____ | 0 | | 0 | | 0 | PAGE1 | 255 | _____ ----- | 0 | | 0 | | 0 | | 0 | -----
Ilustracja do pamięci segmentowej z 4-bajtowymi segmentami przesuniętymi o 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 | ----- ----- ----- -----
Jak widać, czwarty bajt można adresować na cztery sposoby: (adresowanie od 0)
- Segment 0, przesunięcie 3
- Segment 1, przesunięcie 2
- Segment 2, przesunięcie 1
- Segment 3, przesunięcie 0
To zawsze ta sama komórka pamięci.
W rzeczywistych implementacjach segmenty są przesuwane o więcej niż 1 bajt (dla 8086 było to 16 bajtów).
Co jest złego w segmentacji, to to, że jest skomplikowana (ale myślę, że już to wiesz;) To, co jest dobre, polega na tym, że możesz użyć sprytnych technik do tworzenia programów modułowych.
Na przykład, możesz załadować moduł do segmentu, a następnie udawać, że segment jest mniejszy niż jest w rzeczywistości (na tyle mały, aby pomieścić moduł), a następnie wybrać pierwszy segment, który nie nakłada się na ten pseudo-mniejszy i załadować następny moduł i tak dalej. Zasadniczo otrzymujesz w ten sposób strony o zmiennej wielkości.
Czy masz coś do dodania do wyjaśnienia? Dźwięk w komentarzach. Chcesz przeczytać więcej odpowiedzi od innych użytkowników Stack Exchange, którzy znają się na technologii? Sprawdź cały wątek dyskusji tutaj.