Сегментная и сегментно-страничная организации памяти. Резюме, ключевые термины и контрольные вопросы

09.04.2019

Идея виртуальной памяти может быть реализована через механизм страничной организации. И виртуальная, и вся физическая память в логическом смысле делится на блоки одинакового размера, называемые страницами. Адрес, в этом случае интерпретируется так же, как и при блочной организации ОЗУ, старшие разряды задают номер страницы, а младшие – указывают слово (байт) на странице. Поскольку размеры страниц в виртуальной и физической памяти одинаковы, для формирования физического адреса достаточно преобразовать только номер страницы. Страница является базовой единицей информации, перемещаемой между ОЗУ и жестким диском по требованию механизма преобразования адресов. Преобразование адресов осуществляется через специальные таблицы, называемые страничными таблицами . Каждая программа имеет свою страничную таблицу. Процедура преобразования адреса показана на рис.13.

Возникает вопрос, где хранить страничные таблицы? Первое, что приходит на ум–в оперативной памяти. Однако, в этом случае любое обращение к ОЗУ превращается в два: первое обращение к таблице, второе–по физическому адресу за командой или данными. Производительность резко падает. Чтобы снизить потерю производительности часть страничной таблицы хранят в сверхоперативной памяти, называемой ассоциативный буфер быстрого преобразования адреса , буфер TLB (Translation Lookaside Buffer ) или адресный кэш. Обычно, это множественно-ассоциативный кэш, отличающийся от обычного тем, что информация хранится не блоками, а отдельными словами. Содержимое строки страничной таблицы называют дескриптор страницы, т.е. в строке TLB хранится один дескриптор. При поиске дескриптора страницы в ОЗУ номер виртуальной страницы используется как смещение, а при поиске в буфере TLB–в качестве тега.

Сегментно–страничная организация памяти

При страничной организации предполагается, что виртуальная память – это непрерывный массив со сквозной нумерацией слов, что не всегда можно признать оптимальным. Обычно программа состоит из нескольких частей – кода, данных и стека. Так как заранее неизвестны длины этих составляющих, то удобно, чтобы при программировании каждая из них имела собственную нумерацию слов, начинающуюся с нуля. Для этого организуют систему сегментированной памяти, выделяя в виртуальном пространстве независимые линейные пространства переменной длины, называемые сегментами. Каждый сегмент представляет собой отдельную логическую единицу, содержащую однородную информацию и расположенную в адресном пространстве пользователя. Физическая память также разбивается на сегменты, с независимой адресацией слов внутри сегмента. Каждой составляющей программы выделяется сегмент памяти. И виртуальный, и физический адрес интерпретируется как номер сегмента и смещение внутри сегмента. Для преобразования виртуального адреса в физический используется сегментная таблица.

Недостатком такого подхода является то, что неодинаковый размер сегментов приводит к неэффективному использованию ОП. Так, если ОП заполнена, то при замещении одного из сегментов требуется вытеснить такой, размер которого не менее размера нового. При многократном повторе подобных действии в ОП остается множество свободных участков, недостаточных по размеру для загрузки полного сегмента. Решением проблемы служит сегментно-страничная организация памяти. В ней размер сегмента выбирается не произвольно, а задается кратным размеру страницы. Сегмент может содержать любое, но обязательно целое число страниц, даже если одна из страниц заполнена частично. Возникает определенная иерархия в организации доступа к данным, состоящая из трех ступеней: сегмент, страница, слово. Этой структуре соответствует иерархия таблиц, служащих для перевода виртуальных адресов в физические. В сегментной таблице перечисляются все сегменты данной программы с указанием начальных адресов страничных таблиц. Количество страничных таблиц равно числу сегментов и любая из них определяет расположение каждой из страниц сегмента в памяти, которые могут располагаться не подряд – часть страниц может находиться в ОП, а часть – во внешней. Структуру виртуального адреса и процесс преобразования его в физический адрес иллюстрирует рис. 14. Для получения физического адреса необходим доступ к сегментной и одной из страничных таблиц, поэтому преобразование адреса может занимать много времени. Снижают эти затраты времени применением ассоциативных буферов преобразования адресов (TLB). Поскольку количество сегментов одной программы невелико, сегментная таблица активной (выполняемой в данное время) программы целиком располагается в ассоциативном буфере, а сам буфер представляет собой полностью ассоциативную память.

Страничная память - способ организации виртуальной памяти , при котором единицей отображения виртуальных адресов на физические является регион постоянного размера (т. н. страница ). Типичный размер страницы - 4096 байт, для некоторых архитектур - до 128 КБ .

Поддержка такого режима присутствует в большинстве 32-битных и 64-битных процессоров. Такой режим является классическим для почти всех современных ОС, в том числе Windows и семейства UNIX . Широкое использование такого режима началось с процессора VAX и ОС VMS с конца 1970-х годов (по некоторым сведениям, первая реализация). В семействе x86 поддержка появилась с поколения 386, оно же первое 32-битное поколение.

Решаемые задачи [ | ]

Концепции [ | ]

Адрес, используемый в машинном коде, то есть значение указателя, называется «виртуальный адрес».

Адрес, выставляемый процессором на шину, называется «линейный адрес» (который позже преобразуется в физический).

Запись таблицы страниц обычно содержит в себе следующую информацию:

Число записей в одной таблице ограничено и зависит от размера записи и размера страницы. Используется многоуровневая организация таблиц, часто 2 или 3 уровня, иногда 4 уровня (для 64-разрядных архитектур).

В случае 2 уровней используется «каталог» страниц, в котором хранятся записи, указывающие на физические адреса таблиц страниц. В таблицах содержатся записи, указывающие на страницы данных.

При использовании 3-уровневой организации добавляется надкаталог, хранящий записи, указывающие на несколько каталогов.

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

Формат записей таблиц, их размер, размер страницы и организация таблиц зависит от типа процессора, а иногда и от режима его работы.

Исторически x86 использует 32-битные PTE, 32-битные виртуальные адреса, 4-КБ страницы, 1024 записи в таблице, двухуровневые таблицы. Старшие 10 битов виртуального адреса - номер записи в каталоге, следующие 10 - номер записи в таблице, младшие 12 - адрес внутри страницы.

Начиная с Pentium Pro, процессор поддерживает страницы размером 4 МБ. Однако, чтобы система и программы, запущенные в ней, могли использовать страницы такого размера, технология 4-МБ страниц (hugepages) должна быть соответствующим образом активирована, а приложение настроено на использование страниц такого размера.

В архитектуре x86_64 возможно использовать страницы размером 4 килобайта (4096 байтов), 2 мегабайта, и (в некоторых AMD64) 1 гигабайт.

Если обращение к памяти не может быть оттранслировано через TLB, то микрокод процессора обращается к таблицам страниц и пытается загрузить PTE оттуда в TLB. Если и после такой попытки сохранились проблемы, то процессор исполняет специальное прерывание, называемое «отказ страницы » (page fault). Обработчик этого прерывания находится в подсистеме виртуальной памяти ядра ОС.

Некоторые процессоры (MIPS) не имеют обращающегося к таблице микрокода, и генерируют отказ страницы сразу после неудачи поиска в TLB, обращение к таблице и её интерпретация возлагаются уже на обработчик отказа страницы. Это лишает таблицы страниц требования соответствовать жёстко заданному на уровне аппаратуры формату.

Причины отказа страницы (page fault ):

  • не существует таблицы, отображающей данный регион,
  • PTE не имеет взведённого флага «страница отображена»,
  • попытка обратиться из пользовательского режима к странице «только для ядра»,
  • попытка записи в страницу «только для чтения»,
  • попытка исполнения кода из страницы «исполнение запрещено».

Обработчик отказов в ядре может загрузить нужную страницу из файла или же из области подкачки (см. свопинг), может создать доступную на запись копию страницы «только для чтения», а может и возбудить исключительную ситуацию (в терминах UNIX - сигнал SIGSEGV) в данном процессе.

Каждый процесс имеет свой собственный набор таблиц страниц. Регистр «каталог страниц» перегружается при каждом переключении контекста процесса. Также необходимо сбросить ту часть TLB, которая относится к данному процессу.

В большинстве случаев ядро ОС помещается в то же адресное пространство, что и процессы, для него резервируются верхние 1-2 гигабайта 32-битного адресного пространства каждого процесса. Это делается с целью избежать переключения таблиц страниц при входе в ядро и выходе из него. Страницы ядра помечаются как недоступные для кода режима пользователя.

Память региона ядра часто совершенно одинакова для всех процессов, однако некоторые подрегионы региона ядра (например, регион Windows, где находится подсистема графики и драйвер видео) могут быть различными для разных групп процессов (сессий).

Так как память ядра одинакова у всех процессов, соответствующие ей TLB не нужно перегружать после переключения процесса. Для этой оптимизации x86 поддерживает флаг «глобальный» у PTE.

Отображаемые в память файлы [ | ]

Обработчик отказа страницы в ядре способен прочитать данную страницу из файла.

Это приводит к возможности лёгкой реализации отображенных в память файлов. Концептуально это то же, что выделение памяти и чтение в неё отрезка файла, с той разницей, что чтение осуществляется неявно «по требованию», выраженному отказом страницы при попытке обращения к ней.

Вторым преимуществом такого подхода является - в случае отображения «только для чтения» - разделение одной и той же физической памяти между всеми процессами, отображающими данный файл (выделенная же память своя у каждого процесса).

Третьим преимуществом является возможность «забывания» (discard) некоторых отображенных страниц без выгрузки их в область подкачки, обязательной для выделенной памяти. В случае повторной потребности в странице она может быть быстро загружена из файла снова.

Четвёртым преимуществом является неиспользование дискового кэша в этом режиме, что означает экономию на копировании данных из кэша в запрошенный регион. Преимущества дискового кэша, оптимизирующего операции небольшого размера, а также повторное чтение одних и тех же данных, полностью исчезают при чтениях целых страниц и тем более их групп, недостаток же в виде обязательного лишнего копирования - сохраняется.

Отображаемые в память файлы используется в ОС Windows, а также ОС семейства UNIX, для загрузки исполняемых модулей и динамических библиотек. Они же используются утилитой GNU grep для чтения входящего файла, а также для загрузки шрифтов в ряде графических подсистем.

Страничная и сегментная виртуальная память [ | ]

Огромным достоинством страничной виртуальной памяти по сравнению с сегментной является отсутствие «ближних» и «дальних» указателей.

Наличие таких концепций в программировании уменьшает применимость арифметики указателей и приводит к огромным проблемам с переносимостью кода с/на такие архитектуры. Так, например, значительная часть ПО с открытым кодом изначально разрабатывалась для бессегментных 32-битных платформ со страничной памятью и не может быть перенесена на сегментные архитектуры без серьёзной переработки.

Кроме того, сегментные архитектуры имеют тяжелейшую проблему SS != DS, широко известную в начале 1990-х годов в программировании под 16-битные версии Windows. Эта проблема приводит к затруднениям в реализации динамических библиотек, ибо они имеют свой собственный DS, и SS текущего процесса, что приводит к невозможности использования «ближних» указателей в них. Также наличие своего собственного DS в библиотеках требует устанавливающих правильное значение DS заплаток (MakeProcInstance) для обратных вызовов из библиотеки в вызвавшее приложение.

Виртуальная память и дисковый кэш [ | ]

Основная статья: (англ. )

Поддержка файлов, отображенных в память, требует поддержки ядром ОС структуры «совокупность физических страниц, содержащих в себе отрезки данного файла». Отображение файла в память делается путём заполнения входов таблиц ссылками на страницы данной структуры.

Совершенно очевидно, что данная структура является уже готовым дисковым кэшем. Использование её в качестве кэша также решает проблему когерентности файла, доступного через read/write, и его же, отображённого в память.

Таким образом, пути кэшированного ввода-вывода в дисковый файл (FsRtlCopyRead в Windows и аналогичная ей generic_file_read() в Linux) реализуются как копирования данных в физические страницы, отображенные на файл.

Такая организация кэша является единственной в Windows, эта ОС вообще не имеет классического блочного кэша диска. Метаданные файловых систем кэшируются путём создания лже-файлов (IoCreateStreamFileObject) и создания страничного кэша для них.

Соображения безопасности [ | ]

Первоначально архитектура x86 не имела флага «страница недоступна на исполнение» ().

Поддержка данного флага появилась в архитектуре x86 как часть режима PAE (Physical Address Extension) в поколении Pentium 4, под большим давлением со стороны специалистов по безопасности (см. архивы NTBugTraq). Установка данного флага на страницах стека и кучи (heap) позволяет реализовать аппаратно защиту от исполнения данных, что делает невозможной работу многих разновидностей вредоносного ПО, в том числе, например, злонамеренную эксплуатацию многих брешей в Internet Explorer (брешь декабря 2008 года, см. MS knowledge base, не может быть задействована в случае включенной DEP).

Поддержка PAE в Windows, дающая возможность включения защиты от исполнения данных , появилась в Windows 2000, она включена по умолчанию в серверных версиях Windows и отключена в клиентских.

Поддержка памяти свыше 4 ГБ в Windows [ | ]

Устройства PCI, в том числе память видеоплаты, обычно поддерживают только 32-битные адреса. Следовательно, им должны быть выданы физические адреса ниже отметки 4 ГБ. Эта «апертура» уменьшает объём видимой физической памяти ниже отметки 4 ГБ до примерно 3,2 ГБ. Остальная часть физической памяти переотображается контроллером выше отметки 4 ГБ.

Для любого обращения к памяти свыше отметки 4 ГБ (то есть более чем примерно 3,2 ГБ) требуется поддержка контроллером (то есть северным мостом чипсета) такой конфигурации. Современные чипсеты (например, Intel G33) такую поддержку имеют.

Также требуется настройка BIOS под названием memory remapping , отображающая регион на .

Процессор x86 вне режима PAE использует 32-битные PTE и физические адреса, то есть ему не доступно ничто, находящееся выше отметки 4 ГБ (см. также PSE-36 об одном из вариантов обхода данного ограничения). Таким образом, для использования памяти более, чем примерно 3,2 ГБ в ОС она должна поддерживать PAE. Для Windows - это опция загрузки, для Linux - опция построения ядра.

Кроме того, Microsoft принудительно отключила поддержку физических адресов выше 4 ГБ по политико-маркетинговым соображениям в следующих ОС:

Поддержка физических адресов выше 4 ГБ имеется в следующих версиях:

  • всe 64-битные версии,
  • 32-битная Windows Vista SP1 (поддержка включена по умолчанию, но её подключение нередко может требовать набора команд в командной строке),
  • 32-битный Windows Server 2003, отличный от Web Edition,
  • 32-битный Windows Server 2008.

Таким образом, для того, чтобы использовать память выше 3,2 ГБ в Windows, нужны:

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

Тем не менее, даже в «урезанной» версии Windows, не поддерживающей адреса выше 4 ГБ, имеет смысл всегда использовать PAE, ибо (см. выше) защита от исполнения данных (DEP) тоже требует PAE. При включении PAE может перестать работать небольшая часть ПО, например, эмулятор windows mobile. Согласно официальной версии Microsoft, введение 4-ГБ ограничения адресного пространства связано с отсутствующей или плохой поддержкой 36-битного адресного пространства некоторыми драйверами устройств, это следует иметь в виду, по причине аппаратных ограничений или неподходящих драйверов невозможно подключить PAE на версиях, имеющих поддержку физических адресов выше 4 ГБ. Возможность включения или выключения PAE не зависит от драйверов, но, если драйвер какого-то старого PCI оборудования не поддерживает правильно физические адреса, не умещающиеся в 32 бита, то данное устройство будет работать неверно и может привести к зависанию всего компьютера.

СТРАНИЧНАЯ ОРГАНИЗАЦИЯ

Как разделы с разными фиксированными размерами, так и разделы переменного размера недостаточно эффективно используют память. Результатом работы первых становится внутренняя фрагментация, результатом работы последних - внешняя. Предположим, однако, что основная память разделена на одинаковые блоки относительно небольшого фиксированного размера. Тогда блоки процесса, известные как страницы (pages), могут быть связаны со свободными блоками памяти, известными как кадры (frames), или фреймы. Каждый кадр может содержать одну страницу данных. При такой организации памяти, как вы узнаете из этого раздела, внешняя фрагментация отсутствует вовсе, а потери из-за внутренней фрагментации ограничены частью последней страницы процесса.

На рис. 7.9 показано использование страниц и кадров. В любой момент времени некоторые из кадров памяти используются, а некоторые свободны. Операционная система поддерживает список свободных кадров. Процесс А, хранящийся на диске, состоит из четырех страниц. Когда приходит время загрузить этот процесс в память, операционная система находит четыре свободных кадра и загружает страницы процесса А в эти кадры (рис. 7.9,6). Затем загружаются процесс В, состоящий из трех страниц, и процесс С, состоящий из четырех страниц. После этого процесс В приостанавливается и выгружается из основной памяти. Позже наступает момент, когда все процессы в памяти оказываются заблокированы, и операционная система загружает в память новый процесс D, состоящий из пяти страниц.

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

На рис. 7.10 показаны различные таблицы страниц, после того как процесс D оказывается загруженным в страницы 4, 5, 6, 11 и 12. Таблица страниц содержит по одной записи для каждой страницы процесса, так что таблицу легко проиндексировать номером страницы, начиная с 0. Каждая запись содержит номер фрейма в основной памяти (если таковой имеется), в котором хранится соответствующая страница. Кроме того, операционная система поддерживает единый список свободных (т.е. не занятых никаким процессом и доступных для размещения в них страниц) кадров.

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

Для удобства работы с такой схемой добавим правило, в соответствии с которым размер страницы (а, следовательно, и размер кадра) должен представлять собой степень 2. При использовании такого размера страниц легко показать, что относительный адрес, который определяется относительно начала программы, и логический адрес, представляющий собой номер кадра и смещение, идентичны. Соответствующий пример приведен на рис. 7.11. Здесь используется 16-битовый адрес и страницы размером 1 Кбайт = 1024 байт. Относительный адрес 1502 в бинарном виде записывается как 0000010111011110. При размере страницы в 1 Кбайт поле смещения требует 10 бит, оставляя 6 бит для номера страницы. Таким образом, программа может состоять максимум из 2 6 = 64 страниц по 1 Кбайт каждая. Как показано на рис. 7.11, относительный адрес 1502 соответствует смещению 478 (0111011110) на странице 1 (000001), что дает то же бинарное число 0000010111011110.

Использование страниц с размером, равным степени двойки, приводит к таким следствиям. Во-первых, схема логической адресации прозрачна для программиста, ассемблера и компоновщика. Каждый логический адрес (номер страницы и смещение) программы идентичен относительному адресу. Во-вторых, при этом относительно просто реализуется аппаратная функция преобразования адресов во время работы. Рассмотрим адрес из п+т бит, где крайние слева п бит представляют собой номер страницы, а крайние справа m бит - смещение. В нашем примере (рис. 7.11,6) п = 6 и т = 10. Для преобразования адреса необходимо выполнить следующие шаги.

Выделить номер страницы, который представлен п левыми битами логического адреса.

Используя номер страницы в качестве индекса в таблице страниц процесса, найти номер кадра k.

Начальный физический адрес кадра - k´2"", и интересующий нас физический адрес представляет собой это число плюс смещение. Такой адрес не надо вычислять - он получается в результате простого добавления номера кадра к смещению.

В нашем примере имеется логический адрес 0000010111011110, представляющий страницу номер 1 и смещение 478. Предположим, что эта страница размещена в кадре основной памяти номер 6 (бинарное представление - 000110). В таком случае физический адрес представляет собой кадр 6, смещение 478, т.е. 0001100111011110 (рис. 7.12,а).

Итак, в случае простой страничной организации основная память разделяется на множество небольших кадров одинакового размера. Каждый процесс разделяется на страницы того же размера, что и кадры; малые процессы требуют меньшего количества кадров, большие - большего. При загрузке процесса в память все его страницы загружаются в свободные кадры, и информация о размещении страниц заносится в соответствующую таблицу. Такой подход позволяет избежать множества присущих распределению памяти проблем.

СЕГМЕНТАЦИЯ

Альтернативным способом распределения пользовательской программы является сегментация. В этом случае программа и связанные с нею данные разделяются на ряд сегментов. Хотя и существует максимальный размер сегмента, на них не накладывается условие равенства размеров. Как и при страничной организации, логический адрес состоит из двух частей, в данном случае - номера сегмента и смещения.

Использованием сегментов разного размера этот способ похож на динамическое распределение памяти. Если не используются оверлеи и виртуальная память, то для выполнения программы все ее сегменты должны быть загружены в память; однако в отличие от динамического распределения в этом случае сегменты могут занимать несколько разделов, которые, к тому же, могут не быть смежными. Сегментация устраняет внутреннюю фрагментацию, однако, как и динамическое распределение, страдает от фрагментации внешней. Тем не менее ее степень снижается, в силу того что процесс разбивается на ряд небольших частей.

В то время как страничная организация невидима для программиста, сегментация, как правило, видима и обычно используется при размещении кода и данных в разных сегментах. При использовании принципов модульного программирования как код, так и данные могут быть дополнительно разбиты на сегменты. Главным недостатком при работе с сегментами является необходимость заботиться о том, чтобы размер сегмента не превысил максимальный.

Еще одно следствие того, что сегменты имеют разные размеры, состоит в отсутствии простого соотношения между логическими и физическими адресами. Аналогично страничной организации, схема простой сегментации использует таблицу сегментов для каждого процесса и список свободных блоков основной памяти. Каждая запись таблицы сегментов должна содержать стартовый адрес сегмента в основной памяти и его длину, чтобы обезопасить систему от использования некорректных адресов. При работе процесса адрес его таблицы сегментов заносится в специальный регистр, используемый аппаратным обеспечением. Рассмотрим адрес из п+т бит, где крайние слева п бит являются номером сегмента, а правые т бит - смещением. В нашем примере, помещенном на рис. 7.11,в, n = 4 и т - 12. Таким образом, макси­мальный размер сегмента составляет 2 12 = 4096. Для трансляции адреса необходимо выполнение следующих действий.

Выделить из логического адреса п крайних слева битов, получив таким образом номер сегмента.

Используя номер сегмента в качестве индекса в таблице сегментов процесса, найти физический адрес начала сегмента.

Сравнить смещение, представляющее собой крайние справа т бит, с длиной сегмента. Если смещение больше длины, адрес некорректен.

Требуемый физический адрес представляет собой сумму физического адреса начала сегмента и смещения.

В нашем примере имеется логический адрес 0001001011110000, представляющий собой сегмент номер 1, смещение 752, Предположим, что этот сегмент располагается в основной памяти начиная с физического адреса 0010000000100000. Тогда интересующий нас физический адрес равен 0010000000100000+001011110000 = 0010001100010000 (см. рис. 7.12,6).

Итак, в случае простой сегментации процесс разделяется на ряд сегментов, размер которых может быть разным. При загрузке процесса все его сегменты размещаются в свободных областях памяти, и соответствующая информация вносится в таблицу сегментов.

РЕЗЮМЕ, КЛЮЧЕВЫЕ ТЕРМИНЫ И КОНТРОЛЬНЫЕ ВОПРОСЫ

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

Основными инструментами управления памятью являются страничная организация и сегментация. При страничной организации каждый процесс разделяется на относительно малые страницы фиксированного размера; сегментация позволяет использовать части разного размера. Кроме того, возможно комбинирование сегментации и страничной организации в единой схеме управления памятью.

Ключевые термины

Внешняя фрагментация Логический адрес Страница

Внутренняя фрагментация Относительный адрес Страничная организация

времени исполнения Переносимая загрузка Уплотнение

Динамическое распределение Распределение Управление памятью

Динамическое связывание Редактор связей Физическая организация

Защита Сегментация Фиксированное

Кадр Система двойников распределение

Контрольные вопросы

7.1. Каким требованиям должно удовлетворять управление памятью?

7.2. Почему желательно обеспечить возможность переноса процессов?

7.3. Почему невозможно обеспечить защиту памяти во время компиляции программы?

7.4. По каким причинам может потребоваться обеспечение доступа к одной области памяти нескольким процессам?

7.5. В чем состоит преимущество использования разделов разного размера при использовании схемы фиксированного распределения?

7.6. В чем состоит отличие между внутренней и внешней фрагментацией?

7.7. В чем заключается различие между логическим, относительным и физическим адресами?

7.8. В чем разница между страницей и кадром?

7.9. В чем разница между страницей и сегментом?

Поскольку распределение вытесняется технологиями виртуальной памяти, большинство книг предлагают только поверхностный обзор рассматриваемых в данной главе методов. Одной из наиболее полных и интересных работ является ; обсуждение стратегий распределения памяти имеется и в .

Вопросы компоновки и загрузки рассматриваются во многих книгах, посвященных разработке программ, архитектуре компьютеров и операционным системам. Здесь можно порекомендовать обратиться к книгам [ВЕСК90] и .

ВЕСК90 BeckL. System Software, - Reading, MA: Addison-Wesley, 1990.

CLAR98Clarke D., Merusi D. System Software Programming: The Way Thing Work. - Upper Saddle River, HJ: Prentice Hall, 1998.

KNUT97Кнут Д.Э. Искусство программирования. Том 1. Основные алгоритмы, 3-е изд. - М.: Издательский дом "Вильяме", 2000.

MILE92Milenkovic M. Operating Systems: Concepts and Design. - New York: I- McGraw-Hill, 1992.


ЗАДАЧИ

7.1. В разделе 2.3 были перечислены пять целей управления памятью, а в разделе 7.1 - пять требований. Обоснуйте взаимосвязанность этих списков.

7.2. Рассмотрите схему динамического распределения. Покажите, что в среднем количество свободных блоков памяти ("дыр") в два раза меньше количества выделенных процессам разделов.

7.3. Для реализации различных алгоритмов распределения, обсуждавшихся при рассмотрении динамического распределения (раздел 7.2), необходима поддержка списка свободных блоков памяти. Какова средняя продолжительность поиска для каждого из рассмотренных методов (наилучшего, первого и следующего подходящего)?

7.4. Рассмотрите еще один алгоритм размещения при динамическом распределении - метод наихудшего подходящего, при котором для размещения процесса используется наибольший свободный блок памяти. Каковы его достоинства и недостатки по сравнению с другими рассмотренными методами? Какова средняя длина поиска при этом методе?

7.5. Система двойников используется для распределения блока размером 1 Мбайт.

а. Изобразите в виде, подобном приведенному на рис. 7.6, результат выполнения такой последовательности запросов: запрос А = 70 Кбайт, запрос В = 35 Кбайт, запрос С = 80 Кбайт, освобождение А, запрос D = 60 Кбайт, освобождение В, освобождение D, освобождение С.

б. Приведите представление системы двойников в виде бинарного дерева после освобождения В.

7.6. Рассмотрим систему двойников, в которой некий только что выделенный блок имеет адрес 011011110000.

а. Если размер блока равен 4, то каков бинарный адрес его двойника?

б. Если размер блока равен 16, то каков бинарный адрес его двойника?

7.7. Пусть buddy k (x) - адрес того блока размером 2 k , который является двойником блока по адресу х. Запишите выражение для buddy k (х) .

7.8. Последовательность Фибоначчи определяется следующим образом:

F 0 =0, F l =l,...,F n+2 =F n+1 +F n , n>0

а. Можно ли использовать эту последовательность для разработки системы двойников?

б. Каким достоинством должна обладать такая система двойников по сравнению с описанной в данной главе?

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

В регистре команд использовать относительный адрес и выполнять трансляцию адресов динамически, с содержимым регистра команд в качестве входных данных. Команды ветвления или вызова подпрограммы генерируют относительный адрес, который и заносится в регистр команд.

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

Какой подход следует предпочесть?

7.10. Виртуальный адрес а в страничной системе представляет собой пару (p,w), в которой р - номер страницы, a w - номер байта этой страницы. Пусть z -количество байтов в странице. Найдите формулу, представляющую р и w как функции от z и а.

7.11. Рассмотрим память, в которой смежные сегменты S 1 , S 2 , ..., S n размещаются в порядке их создания от одного конца памяти к другому, как показано ниже:

S 1 S 2 S n Свободно

При создании сегмента S n +1 он размещается непосредственно после сегмента S n даже если некоторые из сегментов S 1 , S 2 , ..., S n были к этому моменту удалены. Когда граница между сегментами (используемыми или удаленными) и свободной памятью достигает конца памяти, используемые сегменты уплотняются, а. Покажите, что доля времени F, затрачиваемая на уплотнение, удовлетворяет следующему неравенству:

s - средняя длина сегмента в словах,

t - среднее время жизни сегмента (в обращениях к памяти),

f - доля памяти, не используемая в установившихся условиях.

Указание: найдите среднюю скорость, с которой рассматриваемая граница движется по памяти, и предположите, что копирование одного слова требует как минимум двух обращений к памяти.

б. Определите F для f = 0.2, t = 1000 и s = 50.

Фрагментация

Фрагментация – это дробление памяти на мелкие не смежные свободные области маленького размера. Фрагментация возникает после выполнения системой большого числа запросов на память, таких, что размеры подходящих свободных участков памяти оказываются немного больше, чем требуемые. Например, если имеется 100 смежных свободных областей памяти по 1000 слов, то после выполнения 100 запросов на память по 999 слов каждый в списке свободной памяти останутся 1000 областей по одному слову.

Фрагментация бывает внутренняя и внешняя . При внешней фрагментации имеется достаточно большая область свободной памяти, но она не является непрерывной. Внутренняя фрагментация может возникнуть вследствие применения системой специфической стратегии выделения памяти, при которой фактически в ответ на запрос память выделяется несколько большего размера, чем требуется, - например, с точностью до страницы (листа ), размер которого – степень двойки. Страничная организация памяти подробно рассматривается далее в данной лекции.

Внешняя фрагментация может быть уменьшена или ликвидирована путем применения компактировки (compaction) – сдвига или перемешивания памяти с целью объединения всех не смежных свободных областей в один непрерывный блок. Компактировка может выполняться либо простым сдвигом всех свободных областей памяти, либо путем перестановки занятых областей, с выбором на каждом шаге подходящей свободной области методом наиболее подходящего. Компактировка возможна, только если связывание адресов и перемещение (см. лекцию 15) происходит динамически. Компактировка выполняется во время исполнения программы.

При компактировке памяти и анализе свободных областей может быть выявлена проблема зависшей задачи : какая-либо задача может "застрять" в памяти, так как выполняет ввод-вывод в свою область памяти (по этой причине откачать ее невозможно). Решение данной проблемы: ввод-вывод должен выполняться только в специальные буфера, выделяемой для этой цели операционной системой.

Страничная организация (paging) – стратегия управления памятью, при которой:

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

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


Цели страничной организации – обеспечить возможность не смежного распределения физической памяти для процессов, а также расширить пространство логической памяти.

При страничной организации логический адрес обрабатывается системой особым образом – как структура (p, d): его старшие разряды обозначают номер страницы , младшие – смещение внутри страницы. Номер страницы (p) трактуется как индекс в таблице страниц, соответствующий элемент которой содержит базовый адрес начала страницы в физической памяти . Смещение внутри страницы (d) добавляется к ее базовому адресу. В результате формируется физический адрес, передаваемый в устройство управления памятью.

Архитектура трансляции адресов при страничной организации изображена на рис. 16.3.

Рис. 16.3. Архитектура трансляции адресов при страничной организации.

На рис. 16.4 приведен пример страничной организации, который демонстрирует, что, в отличие от непрерывной логической памяти процесса, соответствующие фреймы страниц в основной памяти могут быть расположены не смежно: логической странице 0 соответствует фрейм 1, странице 1 – фрейм 4, странице 2 – фрейм 3, странице 3 – фрейм 7.

Рис. 16.4. Пример страничной организации.

На рис. 16.5 приведен другой возможный пример страничной организации: логическая и физическая память разбита на блоки по 4 страницы подряд; в таблице страниц хранится не номер страницы, а номер блока страниц. Например, в элементе 0 таблицы страниц хранится номер блока 5, по которому адрес начала блока вычисляется домножением содержимого элемента таблицы страниц на размер блока, равный 4 (результат – 20).

Рис. 16.5. Пример страничной организации блоками по 4 страницы.

Использования списка свободных фреймов иллюстрируется на рис. 16.6.

увеличить изображение
Рис. 16.6. Список свободных фреймов.

Первоначально список состоит из 5 фреймов. При вводе в систему нового процесса с логической памятью из 4 страниц, после загрузки процесса в память, последовательные логические страницы процесса размещаются в первых по списку физических фреймах. В результате в списке свободных фреймов остается один элемент.

Реализация таблицы страниц

Использование ассоциативной памяти. Таблица страниц – непрерывная область физической памяти. В системе имеется базовый регистр таблицы страниц (page table base register – PTBR), указывающий на таблицу страниц и хранящий ее длину.

Таким образом, при страничной организации любой доступ к памяти требует фактически не одного, а двух обращений в память – одно в таблицу страниц, другок – непосредственно к данным или команде. В этом – некоторый недостаток и неэффективность страничной организации, по сравнению с более простыми методами управления памятью.

В системах с теговой архитектурой, например, "Эльбрус", регистр таблицы страниц (регистр таблицы страниц пользователя – РТСП) содержит дескриптор таблицы страниц, который, кроме ее адреса, содержит также ее длину.

Проблема двух обращений решается введением ассоциативной памяти (cache) страниц, называемой также буфер трансляции адресов (translation lookaside buffer – TLB). Ассоциативная память, по существу, является ассоциативным списком пар вида: (номер страницы, номер фрейма). Ее быстродействие значитель выше, чем у основной памяти и у регистров.

Схема трансляции адресов с использованием ассоциативной памяти изменяется: если номер страницы из логического адреса найден в ассоциативной памяти, то из ее элемента извлекается соответствующий номер фрейма. Если же номер страницы отсутствует в ассоциативной памяти, он выбирается обычным образом из таблицы страниц, но заносится в ассоциативную память. Таким образом, в ассоциативной памяти накапливается информация о наиболее часто используемых страницах.

Модифицированная схема трансляции адресов с использованием TLB иллюстрируется рис. 16.7.

увеличить изображение
Рис. 16.7. Схема трансляции адресов с использованием ассоциативной памяти.

В системах со страничной организацией основная и внешняя память (главным образом дисковое пространство) делятся на блоки или страницы фиксированной длины. Каждому пользователю предоставляется некоторая часть адресного пространства, которая может превышать основную память компьютера и которая ограничена только возможностями адресации, заложенными в системе команд. Эта часть адресного пространства называется виртуальной памятью пользователя. Каждое слово в виртуальной памяти пользователя определяется виртуальным адресом, состоящим из двух частей: старшие разряды адреса рассматриваются как номер страницы, а младшие - как номер слова (или байта) внутри страницы.

Управление различными уровнями памяти осуществляется программами ядра операционной системы, которые следят за распределением страниц и оптимизируют обмены между этими уровнями. При страничной организации памяти смежные виртуальные страницы не обязательно должны размещаться на смежных страницах основной физической памяти. Для указания соответствия между виртуальными страницами и страницами основной памяти операционная система должна сформировать таблицу страниц для каждой программы и разместить ее в основной памяти машины. При этом каждой странице программы, независимо от того находится ли она в основной памяти или нет, ставится в соответствие некоторый элемент таблицы страниц. Каждый элемент таблицы страниц содержит номер физической страницы основной памяти и специальный индикатор. Единичное состояние этого индикатора свидетельствует о наличии этой страницы в основной памяти. Нулевое состояние индикатора означает отсутствие страницы в оперативной памяти.

Для увеличения эффективности такого типа схем в процессорах используется специальная полностью ассоциативная кэш-память, которая также называется буфером преобразования адресов (TLB traнсlation-lookaside buffer). Хотя наличие TLB не меняет принципа построения схемы страничной организации, с точки зрения защиты памяти, необходимо предусмотреть возможность очистки его при переключении с одной программы на другую.



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

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

Следствием такого использования является значительный рост таблиц страниц каждого пользователя. Одно из решений проблемы сокращения длины таблиц основано на введении многоуровневой организации таблиц. Частным случаем многоуровневой организации таблиц является сегментация при страничной организации памяти. Необходимость увеличения адресного пространства пользователя объясняется желанием избежать необходимости перемещения частей программ и данных в пределах адресного пространства, которые обычно приводят к проблемам переименования и серьезным затруднениям в разделении общей информации между многими задачами.

Сегментация памяти

Другой подход к организации памяти опирается на тот факт, что программы обычно разделяются на отдельные области-сегменты. Каждый сегмент представляет собой отдельную логическую единицу информации, содержащую совокупность данных или программ и расположенную в адресном пространстве пользователя. Сегменты создаются пользователями, которые могут обращаться к ним по символическому имени. В каждом сегменте устанавливается своя собственная нумерация слов, начиная с нуля.

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

Для реализации сегментации было предложено несколько схем, которые отличаются деталями реализации, но основаны на одних и тех же принципах.

В системах с сегментацией памяти каждое слово в адресном пространстве пользователя определяется виртуальным адресом, состоящим из двух частей: старшие разряды адреса рассматриваются как номер сегмента, а младшие - как номер слова внутри сегмента. Наряду с сегментацией может также использоваться страничная организация памяти. В этом случае виртуальный адрес слова состоит из трех частей: старшие разряды адреса определяют номер сегмента, средние - номер страницы внутри сегмента, а младшие - номер слова внутри страницы.

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

Таблицы сегментов различных пользователей операционная система хранит в основной памяти. Для определения расположения таблицы сегментов выполняющейся программы используется специальный регистр защиты, который загружается операционной системой перед началом ее выполнения. Этот регистр содержит дескриптор таблицы сегментов (базу и границу), причем база содержит адрес начала таблицы сегментов выполняющейся программы, а граница - длину этой таблицы сегментов. Разряды номера сегмента виртуального адреса используются в качестве индекса для поиска в таблице сегментов. Таким образом, наличие базово-граничных пар в дескрипторе таблицы сегментов и элементах таблицы сегментов предотвращает возможность обращения программы пользователя к таблицам сегментов и страниц, с которыми она не связана. Наличие в элементах таблицы сегментов индикаторов режима доступа позволяет осуществить необходимый режим доступа к сегменту со стороны данной программы. Для повышения эффективности схемы используется ассоциативная кэш-память.

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