• Основная идея пейджинга заключается в том, что при загрузке процесса страница загружает в память только те страницы, которые, как она ожидает, понадобятся процессу (сразу же).

  • Страницы, которые не загружаются в память, помечаются в таблице страниц как недопустимые с помощью двоичного кода invalid. (Остальная часть записи в таблице страниц может быть либо пустой, либо содержать информацию о том, где найти вытесненную страницу на жестком диске.)

  • Если процесс обращается только к тем страницам, которые загружены в память (резидентные страницы памяти), то процесс работает точно так же, как если бы все страницы были загружены в память.

  • С другой стороны, если требуется страница, которая изначально не была загружена, то генерируется ошибка страницы, которая должна быть обработана в несколько этапов:

  1. Сначала проверяется запрошенный адрес памяти, чтобы убедиться, что это был корректный запрос памяти.

  1. Если ссылка была недействительной, процесс завершается. В противном случае страница должна быть загружена в память на страницу.

  1. Находится свободный фрейм, возможно, из списка свободных фреймов.

  1. Планируется операция по диску, чтобы доставить необходимую страницу с диска. (Это обычно блокирует процесс на ожидание ввода-вывода, позволяя другому процессу использовать ЦП в это время.)

  1. Когда операция ввода-вывода завершена, таблица страниц процесса обновляется новым номером фрейма, а двоичный код invalid изменяется, чтобы указать, что теперь это действительная ссылка на страницу.

  1. Теперь инструкция, вызвавшая ошибку страницы, должна быть перезапущена с самого начала (как только этот процесс получит еще одно включение процессора).

  • В крайнем случае, ни одна страница не подгружается для процесса до тех пор, пока она не будет запрошена из-за ошибок страниц. Это известно как пейджинг по требованию.

  • Теоретически каждая инструкция может генерировать несколько страничных ошибок. На практике это происходит очень редко, благодаря локальности ссылок, о которой говорилось в разделе 9.6.1.

  • Хардвер необходим для поддержки виртуальной памяти, так же, как и для пейджинга и свопинга: таблица страниц и вторичная память. (Пространство свопинга, распределение которого обсуждается в главе 12.)

  • Важнейшей частью процесса является то, что инструкция должна быть перезапущена с нуля, как только нужная страница становится доступной в памяти. Для большинства простых инструкций это не представляет большой сложности. Однако некоторые архитектуры позволяют одной инструкции изменять довольно большой блок данных (который может охватывать границу страницы), и если часть данных будет изменена до того, как произойдет сбой страницы, это может вызвать проблемы. Одним из решений является доступ к обоим концам блока перед выполнением инструкции, гарантируя, что необходимые страницы подгрузятся до начала выполнения инструкции.


Материал подготовлен в рамках курса «Программист С».

Всех желающих приглашаем на открытый урок «io_uring: пишем убийцу Nginx». Мы рассмотрим различные методы мультиплексирования ввода-вывода, включая активно развивающийся на данный момент интерфейс ядра Linux io_uring, и попробуем написать на его основе высокопроизводительный асинхронный HTTP-сервер, обгоняющий по производительности даже Nginx.
>> РЕГИСТРАЦИЯ

Комментарии (1)


  1. oleshii
    04.09.2021 12:06
    +1

    ИМХО: Не хочу ни с кем спорить и доказывать кому ли бо что либо. Просто высказываю мнение. Я бы сказал, к С это отношения имеет весьма косвенное. Больше - к концепции построения современных GPOS. Да, да, согласен: на 90% они написаны на С. Но есть и исключения. Например, OS X / IoS аппаратные frameworks написаны в виде семейств umbrella драйверов на С++, Symbian от Nokia также на C++. Наверное, есть что то ещё, навскидку сказать не могу.