0:00
[МУЗЫКА]
[МУЗЫКА] [МУЗЫКА]
Теперь мы поговорим о таком интересном понятии, как виртуальная память.
Virtualis — по-латыни означает объект, который не существует,
но может возникнуть.
И вообще, virtual — это что-то выдуманное.
Так вот, представьте себе, что у вас есть память, ну скажем, 1 мегабайт.
Я буду говорить в примерах, которые мне привычны, в старые времена.
А вам хочется программировать, естественно, в большей памяти, скажем,
в 100 мегабайт.
Так вот, можно придумать систему, которая будет в каком-то смысле вас обманывать,
создавать у вас иллюзию, что у вас есть 100 мегабайт.
И вот это и называется виртуальная память.
Давайте разберемся, как это делается.
Память делится на страницы фиксированного размера.
Принято 2 или 4 килобайта.
И дальше вы работаете только с математическими адресами.
Математический адрес — это пара.
Номер страницы и смещение на три страницы.
Никаких прямых физических адресов нет.
Каждый раз, когда вам нужно обратиться к объекту,
вы пользуетесь математическим адресом и начинаете с того, что по
номеру страницы операционная система лезет в так называемую таблицу страниц.
Есть такой объект в операционной системе — таблица страниц.
В этой таблице по номеру страницы можно определить,
находится ли страница в оперативной памяти,
и если находится, то прямо в таблице адрес ее начала.
Или если она не находится, то где ее найти на диске?
То есть вся идея в том, что у вас есть, если вы помните,
1 мегабайт оперативной памяти, сколько-то страниц у вас там помещается,
а все остальные страницы хранятся на диске.
И вот вы по номеру страницы полезли в таблицу страниц,
определили, что нужная страница находится в памяти,
получили ее адрес начала и прибавляете к нему смещение.
Тем самым вы получаете настоящий физический адрес,
по которому вы начинаете писать.
Ежели страницы в памяти нет, то возникает прерывание операционной системы,
и она своими способами там на диске ищет нужный адрес,
считает нужную страницу в память, и дальше все, как раньше мы говорили.
Адрес в начало, плюс смещение — вот ваш физический адрес.
Заметьте, что это процесс такой сложный, и если у
вас страницы не оказалось в памяти, и вам надо подкачать ее с диска, то, возможно,
вам какие-то страницы придется выгнать из оперативной памяти на диск, выгрузить.
Так что ни о какой скорости там даже говорить вообще не приходится.
То есть давайте повторим главный принцип виртуальной памяти: виртуальная
память запрещает использование прямых физических адресов, только математические.
Заметьте, они относительные такие — номер страницы и смещение в эту страницу.
Итак, математический адрес — это пара: номер страницы и смещение,
а физический адрес — это адрес нормальной оперативной памяти.
Так вот, перед каждым использованием математического адреса,
его надо преобразовать в физический адрес.
Если страницы нет в оперативной памяти,
то говорить о скорости тут вообще не приходится.
То есть это будет тысячи больших, тысячи команд.
Если находится, то прибавляется смещение.
Причем это тоже некоторое замедление, и нельзя сказать, что это хорошо.
Но я же вам в самом начале сказал, что вас обманывают, вам говорят,
что у вас есть 100 мегабайтов, хотя реально есть только один мегабайт.
Но зато программировать удобнее.
Просто программировать в большой памяти, и все программисты это понимают,
намного легче, чем программировать в маленькой, ограниченной памяти.
Поэтому за такой обман приходится платить.
И люди обычно на это идут.
То есть в наше время стоимость труда программиста много дороже,
чем стоимость машины.
Слушайте, вот тут, поскольку я старый программист, не могу не сказать,
что когда-то машины стоили миллионы (в советское время — миллионы рублей),
а зарплата программиста была 100–200 рублей.
И тогда надо было экономить машинное время, и, в общем,
некоторые усилия предпринимались, чтобы как-то сэкономить использование машины.
А с течением времени, сегодня вот компьютер можно купить тысяч за 30–40,
а зарплата программиста, как минимум, в два раза больше.
То есть сегодня все происходит наоборот — компьютеры дешевые (все относительно,
но, тем не менее, я настаиваю на этом), а рабочая сила программистов — дорогая.
Поэтому надо экономить усилия программистов.
И в этом смысле виртуальная память — отличный пример,
что вы экономите усилия программистов,
расплачиваясь за это некоторым понижением эффективности использования компьютера.
Черт с ним, зато программисты работают в более комфортных условиях,
и это для нас важно.
Тем не менее, можно бороться с виртуальной памятью, и ее тоже ускорять.
Во-первых, оказалось, что есть такое понятие — рабочее множество страниц.
То есть в любой программе всегда есть какой-то процент, 5–10 страниц,
в которых происходит 90–95 % обращений.
То есть далеко не все страницы программы и их данные используются равномерно.
Так вот, такое множество страниц, которое в основном работает,
называется рабочим множеством страниц.
И современная операционная система умеет их выделять и сохранять в
основную оперативную память.
Поэтому чаще всего, когда вы работаете с виртуальной памятью,
в 90 % случаев страница в памяти находится.
Хотя, конечно, преобразование, обратиться к таблице страниц, прибавить смещение,
все равно занимает какое-то время.
Но уже это исчезающе мало, по сравнению с поиском страницы на диске.
Чтобы сэкономить время в работе с этой таблицей страниц,
придумали специальный механизм TLB (Translation lookaside buffer).
Это тоже кэш-память, о которой мы уже говорили, только очень специализированная.
В этой кэш-памяти, в этой TLB, оседают адреса начала страниц,
которые чаще всего используются.
И поскольку TLB хранится в быстрой кэш-памяти,
то преобразование происходит быстрее.
Таким образом, происходит экономия на времени чтения адреса начала страницы.
Теперь поговорим об обработке ошибок.
При работе с памятью регулярно возникают ошибки.
Вы знаете, я не большой специалист в физике, но инженеры говорят,
что прилетит какая-то альфа-частица и может исказить какой-то вид в памяти.
Я не ручаюсь, что так это или не так, но меня так учили.
Ну и теперь я так учу.
Во всяком случае, даже сегодня (хотя сегодня электроника стала намного более
надежной, чем, скажем, 20 лет назад), тем не менее, память бывает сбоит.
Как с этим бороться?
Опять-таки инженеры знают, что надежность — это избыточность.
Есть такая знаменитая теорема, по-моему, теорема Котельникова, что можно
сделать сколько угодно надежное устройство из скольки угодно ненадежных элементов.
Вот вслушайтесь: элементы сколько угодно ненадежны,
но можно даже из них сделать сколь угодно надежные устройства.
То есть понятно за счет чего?
За счет избыточности.
Все блоки повторять, дублировать, троировать, учетверять и так далее,
делать специальные схемы сравнения — и можно добиться надежности.
Но с точки зрения работы с памятью, все относительно проще, а именно,
проще всего к каждому байту добавить девятый бит — бит четности называется.
То есть складываете все разряды этого байта и контрольный бит тоже,
как договоримся.
Если получается 0 — то значит, все в порядке.
А если 1, то значит, какой-то бит исказился.
То есть в правильно записанном байте сумма всех битов должна быть равна нулю.
Поскольку бит четности определяет ошибку,
но не позволяет исправить ошибку, были придуманы более сложные коды.
Самый популярный из них — это код Хэмминга.
Я не хочу влезать в технические детали, но можно на 16 разрядов
добавить 5 контрольных разрядов, в которых будут храниться контрольные
суммы побитовые по 1-й, по 2-й, по 4-й, по 8-й позициям.
И вот наличие вот этих пяти дополнительных битов позволяет а) обнаружить ошибку,
если какая-то позиция испортилась; б) исправить ее.
На самом деле, существуют и более сложные коды.
Это вообще тема отдельного курса — теория кодирования.
И надо сказать, что эта теория кодирования на Западе
приписывается Клоду Шеннону, а у нас Котельникову и его школе.
Был такой академик Котельников.
Есть такая теорема кодирования Шеннона,
которая на Западе все вот именно так производит, так вот я утверждаю,
что ровно эта теорема была опубликована еще в конце 30-х годов в докладах Академии
наук, которые переводились на английский, на французский, на немецкий языки.
Ну так часто бывало и раньше, к сожалению, это бывает и сейчас.
Тем не менее, мне важно сказать вот что: есть специальные системы кодирования,
которые позволяют не только находить ошибки, но и исправлять их.
Но еще раз повторю, что это тема отдельного курса.