Колко памет адреси може да RAM в моя компютър?
Някой ден е забавно да се гледа на повърхностното ниво на компютърния опит, а други дни е забавно да се ровиш във вътрешната работа. Днес ще разгледаме структурата на паметта на компютъра и колко неща можете да опаковате в стик RAM.
Днешната сесия за въпроси и отговори идва при нас с любезното съдействие на SuperUser - подразделение на Stack Exchange, групирано от общността уеб сайтове за въпроси и отговори.
Въпроса
Читателят на SuperUser Johan Smohan се бори с начина, по който типът на процесора и размерът на паметта работят заедно, за да се получи общ брой адреси. Той пише:
Колко памет може да получим с 32-битов процесор и 1GB оперативна памет и с 64-битов процесор?
Мисля, че това е нещо подобно:
1GB овен, разделен от 32 бита (4), за да получи броя на адресите в паметта?
Прочетох в Уикипедия, че 1 адрес на паметта е 32 бита широк или 4 октета (1 октет = 8 бита), в сравнение с 64-битов процесор, където 1 памет или 1 цяло число е 64 бита широк или 8 октета. Но не знам дали съм го разбрал правилно.
Това са типовете въпроси, които могат да поддържат любопитен маниак през нощта. Колко са адресите за всяка от хипотетичните системи на Йохан?
Отговорът
Сътрудникът на SuperUser Gronostaj предлага известна информация за това как RAM е разделена и използвана:
Кратък отговор: Броят на достъпните адреси е равен на по-малките от тях:
- Размер на паметта в байтове
- Най-голямото цяло число без знака, което може да бъде записано в машинната дума на процесора
Дълъг отговор и обяснение на горното:
Паметта се състои от байтове (B). Всеки байт се състои от 8 бита (b).
1 B = 8 b
1 GB RAM всъщност е 1 GiB (gibibyte, а не гигабайт). Разликата е:
1 GB = 10 ^ 9 B = 1 000 000 000 B 1 GiB = 2 ^ 30 B = 1 073 741 824 B
Всеки байт памет има свой адрес, без значение колко голяма е думата на процесора. Напр. Процесорът Intel 8086 беше 16-битов и се занимаваше с памет по байтове, както и с модерните 32-битови и 64-битови процесори. Това е причината за първия лимит - не можете да имате повече адреси, отколкото байтове от паметта.
Адресът на паметта е само броят на байтовете, които CPU трябва да прескочи от началото на паметта, за да стигне до това, което търси.
- За достъп до първия байт той трябва да пропусне 0 байта, така че първият байт адрес е 0.
- За достъп до втория байт трябва да пропусне 1 байт, така че адресът му е 1.
- (и така нататък… )
- За достъп до последния байт, процесорът прескача 1073741823 байта, така че адресът му е 1073741823.
Сега трябва да знаете какво всъщност означава 32-битов. Както вече споменах, това е размерът на машинна дума.
Машинната дума е количеството памет, което CPU използва за задържане на номера (в RAM, кеш или вътрешни регистри). 32-битовият CPU използва 32 бита (4 байта) за задържане на номера. Адресите на паметта също са номера, така че на 32-битов процесор адресът на паметта се състои от 32 бита.
Сега помислете за това: ако имате един бит, можете да запишете две стойности: 0 или 1. Добавете още един бит и имате четири стойности: 0, 1, 2, 3. На три бита можете да запазите осем стойности. : 0, 1, 2… 6, 7. Това всъщност е двоична система и работи така:
Двоично десетично число 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
Работи точно като обичайното допълнение, но максималната цифра е 1, а не 9. Десетична стойност 0 е
0000
, след това добавяте 1 и получавате0001
, добавете още веднъж и имате0010
. Това, което се случи тук, е като с десетичен знак09
и добавяне на: променяте 9 на 0 и увеличавате следващата цифра.От примера по-горе можете да видите, че винаги има максимална стойност, която можете да задържите в число с постоянен брой битове - защото, когато всички битове са 1 и се опитате да увеличите стойността с 1, всички битове ще станат 0, като по този начин се прекъсне номер. Тя се нарича цялостно препълване и причинява много неприятни проблеми както за потребителите, така и за разработчиците.
11111111 = 255 + 1 ----------- 100000000 = 0 (9 бита тук, така че 1 се изрязва)
- За 1 бит най-голямата стойност е 1,
- 2 бита - 3,
- 3 бита - 7,
- 4 бита - 15
Най-големият възможен брой винаги е 2 ^ N-1, където N е броят на битовете. Както казах преди, адресът на паметта е число и също има максимална стойност. Ето защо размерът на машинната дума също е ограничение за броя на наличните адреси в паметта - понякога процесорът не може да обработи достатъчно големи числа, за да адресира повече памет.
Така че на 32 бита можете да запазите номера от 0 до 2 ^ 32-1, и това е 4 294 967 295. Това е повече от най-големия адрес в 1 GB RAM, така че в конкретния случай количеството на RAM ще бъде ограничаващ фактор.
Ограничението за RAM за 32-битов CPU е теоретично 4 GB (2 ^ 32), а за 64-битова CPU е 16 EB (exabytes, 1 EB = 2 ^ 30 GB). С други думи, 64-битовият CPU може да адресира целия интернет… 200 пъти;) (оценен от WolframAlpha).
Въпреки това, в реални операционни системи 32-битовите процесори могат да адресират около 3 GiB на RAM. Това се дължи на вътрешната архитектура на операционната система - някои адреси са запазени за други цели. Можете да прочетете повече за така наречената 3 GB бариера в Уикипедия. Можете да вдигнете това ограничение с разширение Physical Address Extension.
Говорейки за адресиране на паметта, има няколко неща, които трябва да спомена: виртуална памет, сегментиране и пейджинг.
Виртуална памет
Както @ Daniel R Hicks посочи в друг отговор, операционните системи използват виртуална памет. Това означава, че приложенията всъщност не работят с реални адреси на паметта, а такива, предоставени от ОС.
Тази техника позволява на операционната система да премести някои данни от RAM в така наречения Pagefile (Windows) или Swap (* NIX). HDD е малко по-бавен от RAM, но това не е сериозен проблем за рядко достъпни данни и позволява на операционната система да предоставя приложения повече RAM, отколкото всъщност сте инсталирали..
пейджинг
Това, за което говорихме досега, се нарича схема за плоско адресиране.
Пейджинг е алтернативна схема за адресиране, която позволява да се адресира повече памет, която обикновено може да се използва с една машинна дума в плосък модел.
Представете си книга, пълна с 4-буквени думи. Да кажем, че на всяка страница има 1024 номера. За да адресирате номер, трябва да знаете две неща:
- Номерът на страницата, на която се отпечатва тази дума.
- Коя дума на тази страница е тази, която търсите.
Това е точно как модерните x86 процесори работят с паметта. Той е разделен на 4 KiB страници (по 1024 машинни думи) и тези страници имат номера. (всъщност страниците могат да бъдат и 4 MiB големи или 2 MiB с PAE). Когато искате да се обърнете към клетка от паметта, трябва да имате номера на страницата и адреса на тази страница. Обърнете внимание, че всяка клетка от паметта е посочена от точно един чифт числа, което не е така за сегментирането.
сегментиране
Е, това е доста подобно на пейджинг. Той е бил използван в Intel 8086, само за да назовем един пример. Групите адреси сега се наричат сегменти на паметта, а не страници. Разликата е, че сегментите могат да се припокриват и те се припокриват много. Например на 8086 повечето клетки от паметта са достъпни от 4096 различни сегмента.
Пример:
Да кажем, че имаме 8 байта памет, всички притежаващи нули, с изключение на 4-ти байт, който е равен на 255.
Илюстрация за модел с плоска памет:
_____ | 0 | | 0 | | 0 | | 255 | | 0 | | 0 | | 0 | | 0 | -----
Илюстрация за странична памет с 4-байтови страници:
Страница0 _____ | 0 | | 0 | | 0 | СТРАНИЦА1 | 255 | _____ ----- | 0 | | 0 | | 0 | | 0 | -----
Илюстрация за сегментирана памет с 4-байтови сегменти, изместени с 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 | ----- ----- ----- -----
Както виждате, 4-ти байт може да бъде адресиран по четири начина: (адресиране от 0)
- Сегмент 0, отместване 3
- Сегмент 1, отместване 2
- Сегмент 2, отместване 1
- Сегмент 3, отместване 0
Винаги е една и съща клетка от паметта.
В реални изпълнения сегментите се изместват с повече от 1 байт (за 8086 е 16 байта).
Какво е лошо за сегментацията е, че е сложно (но мисля, че вече знаете това;) Какво е добро, е, че можете да използвате някои умни техники за създаване на модулни програми.
Например, можете да заредите някой модул в сегмент, след това да се преструвате, че сегментът е по-малък, отколкото в действителност е (достатъчно малък, за да задържите модула), след това изберете първия сегмент, който не се припокрива с този псевдо-по-малък и зарежда следващия модул и т.н. По принцип, това, което получавате по този начин, са страници с променлива големина.
Имате ли какво да добавите към обяснението? Звукът е изключен в коментарите. Искате ли да прочетете повече отговори от други технологични потребители на Stack Exchange? Вижте пълната тема за дискусия тук.