Архитектура компьютера
Виртуальная память: Иллюзия бесконечного пространства
Цели урока
- Понимать, зачем нужна виртуальная память
- Знать структуру виртуального адреса
- Понимать работу многоуровневых таблиц страниц
- Знать роль TLB в производительности
- Понимать Demand Paging и Copy-on-Write
- Знать алгоритмы вытеснения страниц
Предварительные знания
- Иерархия памяти
- Кэш-память
8 ГБ RAM, но программы хотят 20 ГБ. Как это возможно? Виртуальная память создаёт иллюзию бесконечной памяти.
- Запуск множества приложений одновременно
- Защита процессов друг от друга
- Memory-mapped files для работы с большими файлами
- fork() в Unix - быстрое создание процессов
Проблема: Много программ, мало RAM
**Парадокс:** Ваш браузер с 50 вкладками использует 8 ГБ. Видеоредактор - ещё 12 ГБ. У вас всего 16 ГБ RAM. Как это работает?
**Три проблемы без виртуальной памяти:**
| Проблема | Описание | Последствия |
|---|---|---|
| Изоляция | Программы видят всю память | Баг в одной убивает другие |
| Фрагментация | Дыры в памяти | 4 ГБ свободно, но не выделить 1 ГБ |
| Размещение | Компилятор не знает, куда загрузят | Адреса захардкожены |
**В 1960-х:** Программисты вручную делили программы на 'overlays' - части, загружаемые по очереди. Ошибка = краш всей системы!
Главная проблема без виртуальной памяти:
Виртуальное адресное пространство
**Решение:** Каждая программа думает, что у неё ВСЯ память. Это иллюзия - виртуальные адреса.
**Ключевая идея:** CPU работает с виртуальными адресами. MMU (Memory Management Unit) транслирует их в физические.
**32-бит vs 64-бит:** 32-битный процесс видит 4 ГБ (2³²). 64-битный - 16 экзабайт (2⁶⁴), хотя реально используется ~48 бит.
Виртуальный адрес 0x1000 в двух разных процессах:
Страницы и трансляция адресов
**Страница (Page):** Память делится на блоки фиксированного размера. Типично 4 КБ.
**Frame (кадр):** Физическая страница. Страница (виртуальная) отображается на кадр (физический).
| Размер страницы | Бит смещения | Записей в таблице (32-бит) | Плюсы/Минусы |
|---|---|---|---|
| 4 КБ | 12 | 1 миллион | Стандарт, хороший баланс |
| 2 МБ | 21 | 2048 | Меньше записей, но внутренняя фрагментация |
| 1 ГБ | 30 | 4 | Huge pages для больших БД |
**Почему степень 2?** Разделение на номер страницы и смещение - просто битовые операции, никакого деления!
Если страница = 4 КБ (2¹² байт), сколько бит занимает смещение?
Таблица страниц
**Page Table:** Массив, где индекс = номер виртуальной страницы, значение = номер физического кадра + флаги.
**Размер таблицы:** 32-бит, 4 КБ страницы = 2²⁰ записей × 4 байта = 4 МБ на процесс! При 100 процессах = 400 МБ только на таблицы.
Флаг 'Dirty' в PTE означает:
Многоуровневые таблицы
**Проблема:** Плоская таблица занимает 4 МБ даже если программа использует 10 страниц.
**Решение:** Иерархическая структура. Не создавать записи для неиспользуемой памяти.
**Экономия:** Типичная программа использует ~100 МБ = ~25000 страниц. Вместо 4 МБ плоской таблицы - ~100 КБ иерархической!
Зачем нужны многоуровневые таблицы страниц?
TLB - кэш трансляций
**Проблема:** 4 уровня таблиц = 4 обращения к RAM на каждую инструкцию. Это катастрофа!
**TLB (Translation Lookaside Buffer):** Кэш недавних трансляций. Обычно 64-1024 записей.
| TLB | Записей | Время | Покрытие (4 КБ) | Покрытие (2 МБ) |
|---|---|---|---|---|
| L1 ITLB | 64-128 | ~1 нс | 256-512 КБ | 128-256 МБ |
| L1 DTLB | 64-128 | ~1 нс | 256-512 КБ | 128-256 МБ |
| L2 TLB | 512-2048 | ~10 нс | 2-8 МБ | 1-4 ГБ |
**TLB flush:** При переключении процесса - TLB очищается (разные адресные пространства). Это дорого! PCID (Process Context ID) помогает.
TLB - это:
Page Fault - страница не в памяти
**Page Fault:** Исключение, когда страница не в физической памяти (P=0) или нарушены права.
**Цена Hard Fault:** ~10 мс на SSD, ~100 мс на HDD. За это время CPU мог выполнить 40+ миллионов инструкций!
Major Page Fault происходит когда:
Demand Paging и Copy-on-Write
**Demand Paging:** Не загружать страницу, пока не понадобилась. Экономит RAM и ускоряет запуск.
**Copy-on-Write (COW):** При fork() не копировать память, а расшарить read-only. Копировать при записи.
**Redis COW:** Redis использует fork() для сохранения снапшотов. Без COW 10 ГБ Redis потребовал бы 20 ГБ RAM на время записи!
Copy-on-Write при fork() означает:
Swapping и алгоритмы вытеснения
**Swap:** Когда RAM заполнена, вытесняем страницы на диск. Какие вытеснять?
| Алгоритм | Идея | Плюсы | Минусы |
|---|---|---|---|
| FIFO | Вытесняем самую старую | Простой | Belady's anomaly |
| LRU | Давно не использованную | Близок к OPT | Дорогой (временные метки) |
| Clock (2nd chance) | FIFO + Accessed bit | Приближение LRU | Используется на практике |
| LFU | Редко используемую | Хорош для стабильных паттернов | Не адаптируется |
**Thrashing:** Если рабочий набор > RAM, постоянные page faults. Система тратит всё время на swap, а не на работу!
Swap ускоряет работу как кэш
Swap - это спасение при нехватке RAM, но он в 1000× медленнее RAM
Swap на SSD: ~100 МБ/с, RAM: ~50 ГБ/с. Swap - крайняя мера, не оптимизация.
Thrashing - это:
Ключевые идеи
- Виртуальная память изолирует процессы и создаёт иллюзию большой памяти
- MMU транслирует виртуальные адреса в физические
- Страницы = 4 КБ блоки, Page Table хранит отображение
- Многоуровневые таблицы экономят память
- TLB кэширует трансляции (99%+ hit rate)
- Page Fault загружает страницы по требованию
- COW экономит память при fork()
- Swap вытесняет страницы на диск при нехватке RAM
Связанные темы
Виртуальная память - основа современных ОС.
- Кэш-память — TLB - специализированный кэш
- RISC vs CISC — Разные подходы к MMU