Текст книги "Основы AS/400"
Автор книги: Фрэнк Солтис
Жанр:
ОС и Сети
сообщить о нарушении
Текущая страница: 23 (всего у книги 41 страниц)
Одноуровневая виртуальная память
В только что описанной реализации виртуальной памяти программист имеет дело с двумя уровнями хранилища: файловая система и виртуальная память разделены. Двухуровневая система хранения вызывает дополнительные накладные расходы. Открытие файла связано с записью на диск в файлы подкачки, а закрытие – требует записи обратно на место постоянного хранения.
Сам собой напрашивается альтернативный вариант – работать только с одной копией файла. Ведь если нет двух отдельных копий, то не нужно резервировать пространство на диске для файла подкачки. При таком подходе вся файловая система становится частью виртуальной памяти. Менеджер файлов по-прежнему ведет справочник, но теперь он связывает имя файла с местом в памяти, где находятся данные файла. При открытии и закрытии файла не требуется копировать весь файл из его постоянной области хранения на диске. В буфер памяти копируется только та порция (или запись) с которой пользователь в данный момент работает. Часто говорят и так: файлы всегда используются там же, где хранятся. Все это позволяет повысить общую производительность системы.
Одноуровневая память – это именно то, что ставили своей целью создатели первой виртуальной памяти, и именно эта модель была реализована в System/38. В честь первооткрывателей мы решили назвать нашу виртуальную память одноуровневой памятью.
И двухуровневая виртуальная память, и одноуровневая используются как буфер. Процессоры могут работать только с данными в памяти, но не на диске. Отличие одноуровневой схемы в том, что память в ней – кэш для всего дискового пространства, а не только для зарезервированной области диска. Кроме того, после изменения файла одним пользователем, это изменение немедленно становится видимым всем остальным, работающим с тем же файлом.
Недостаток одноуровневой памяти – большой размер адреса. Адрес должен быть достаточно велик, чтобы покрывать все подключенное к системе дисковое пространство. Возьмем 32-разрядный адрес, используемый во многих современных системах. С его помощью можно адресовать до 4 ГБ, что совершенно недостаточно для адресации всего дискового пространства даже на большом ПК. Таким образом, обычные системы просто вынуждены копировать дисковые данные в свои относительно небольшие виртуальные памяти и обратно.
Чтобы устранить это ограничение, в System/38 и первые модели AS/400 был включен 48-разрядный адрес. Теперь AS/400 использует 64-разрядный адрес и для будущих расширений предусмотрены дополнительные разряды адреса. Хоть все это и связано с аппаратными затратами, последние вполне компенсируются возможностями по совместному использованию данных и ростом производительности.
Постоянная виртуальная память
Размер адреса AS/400 значительно превышает необходимый для покрытия всего дискового пространства. Причина такого положения – другая характеристика одноуровневой памяти, называемая постоянством (persistence). Мы уже говорили об этом в главе 5, посвященной объектам. Объект, обладающий постоянством, остается в памяти системы вечно, даже после своего разрушения, и виртуальное адресное пространство такого постоянного объекта никогда не используется повторно. При разрушении постоянного объекта освобождается все занятое им дисковое пространство, за исключением заголовков. Освобожденное дисковое пространство затем используется для других объектов.
То, что виртуальное адресное пространство повторно не используется, устраняет многие проблемы защиты и целостности. Если постоянный объект разрушен и его адресное пространство использовано повторно другим объектом, то любой, у кого был разрешенный указатель на старый объект, сможет адресовать новый объект. Так как указатели могут храниться в памяти где угодно, то большинство схем «сборки мусора» для поиска указателей уничтоженных объектов слишком сложны. В AS/400 же применяется достаточно большой адрес и адресное пространство постоянных объектов повторно не используется. Так что «сборка мусора» в этой системе не нужна.
Большинство обычных систем виртуальной памяти борются со «сборкой мусора» другим способом. В ранних схемах виртуальной памяти (по-прежнему используемых некоторыми ОС ПК), каждому пользователю выделяется отдельное виртуальное адресное пространство. Когда пользовательский процесс прекращает свое существование, то же происходит и с его виртуальной памятью. Сохранить адрес где-либо в системе нельзя. Единственное место разделения данных – файловая система, где виртуальная адресация не используется.
Для большинства многопользовательских ОС, таких как Unix, подобная реализация неприемлема. Вместо того, чтобы предоставить пользовательской программе возможность прямой адресации виртуальной памяти, такие системы передают программе адрес, который перед использованием транслируется в виртуальный аппаратно. В архитектуре PowerPC такой адрес называется эффективным. Как мы увидим далее, эффективный адрес позволяет добиться некоторого уровня разделения памяти, но за счет больших накладных расходов.
Виртуальная память в таких системах логически подразделяется на сегменты – блоки последовательных байтов памяти. Эффективный адрес задает один из таких сегментов. Обычно трансляция эффективного адреса в виртуальный использует несколько (от 4 до 16) регистров микросхемы процессора, которые называются сегментными регистрами. Каждый сегментный регистр содержит виртуальный адрес одного из сегментов памяти. Часть старших разрядов эффективного адреса задают один из сегментных регистров. Остальные же задают байт внутри сегмента (и называются смещением в сегменте). Так как эффективный адрес содержит смещение внутри сегмента виртуального адреса, то данный тип адресации иногда называется адресацией относительно сегмента.
Проще всего представить себе эффективный адрес как подмножество виртуального адреса большего размера. Пользовательская программа может напрямую адресовать лишь несколько сегментов виртуальной памяти – те, чьи адреса загружены в сегментные регистры. Программа может запросить у ОС перезагрузку системных регистров, что позволит ей получить доступ к другим сегментам, но по-прежнему будет работать лишь с небольшой частью виртуальной памяти. Например, на некоторых процессорах Intel – лишь четыре сегментных регистра, что позволяет работать только с четырьмя сегментами одновременно, тогда как некоторые ранние процессоры RS/6000 использовали 16 таких регистров, но все равно могли адресовать лишь небольшую часть общей памяти.
В архитектуре PowerPC мы избавились от сегментных регистров и заменили их специальной таблицей в памяти, так называемой таблицей сегментов. Это дает пользовательским программам доступ к гораздо большему числу сегментов, чем регистровая реализация. Каждая запись таблицы сегментов по-прежнему содержит виртуальный адрес одного из сегментов виртуальной памяти. Эффективный адрес, используемый программой, теперь задает запись таблицы сегментов и байтовое смещение в сегменте. Две программы могут использовать совместно один и тот же виртуальный адрес, если они обращаются к одной и той же записи в таблице сегментов, или если тот же самый виртуальный адрес хранится в нескольких записях таблицы.
В случае адресации относительно сегмента, пользовательской программе виден только эффективный адрес, и таким образом, она не может сохранить где-либо виртуальный адрес. Трансляция эффективного адреса в виртуальный требует дополнительных накладных расходов, но зато виртуальные адреса защищены и не нужна «сборка мусора». Так как только ОС может изменять значения сегментных регистров, то в определенной степени контролируется, какие сегменты пользовательская программа может использовать и разделять с другими программами.
Поскольку эффективный адрес содержит только идентификацию записи таблицы сегментов и смещение адреса, постольку эффективный адрес имеет меньше разрядов, чем виртуальный. Именно благодаря тому, что виртуальный адрес не ограничен размером регистров процессора, 32-разрядный процессор с 32-разрядным виртуальным адресом может поддерживать большее виртуальное адресное пространство. Но даже и в этом случае, эффективный адрес может адресовать лишь подмножество адресного пространства без перезагрузки ОС сегментных регистров. Кроме того, хотя виртуальный адрес может иметь длину более 32 разрядов, отдельная операция по-прежнему использует только 32 разряда адреса. Таким образом, ограничение в 4 ГБ по-прежнему сохраняется, независимо от того, сколько разрядов в виртуальном адресе. Это объясняет, почему даже системы, поддерживающие большие виртуальные адреса, переходят с 32– на 64-разрядные процессоры.
Теперь сопоставим рассмотренную нами адресацию относительно сегмента с одноуровневой памятью AS/400. Одноуровневая память и виртуальные адреса располагаются ниже MI и не видны пользователю. Таким образом, для защиты адресов не требуется дополнительный уровень трансляции (эффективного адреса в виртуальный), она осуществляется с помощью указателей. Защищая указатели (с помощью разрядов тега), не надо идти на дополнительные накладные расходы, связанные с загрузкой и сохранением таблиц сегментов для каждой программы.
Как уже упоминалось при обсуждении структуры объектов, в AS/400 одноуровневая память также разделена на сегменты. Важно то, что при использовании одноуровневой памяти большой адрес AS/400 (48 и 64-разрядный) позволяет программе ниже MI адресовать любой сегмент всего адресного пространства, а не только подмножество сегментов, как в модели адресации относительно сегмента. Программа может обращаться ко всей виртуальной памяти, а сама виртуальная память может быть разделяемой без каких-либо накладных расходов.
Что такое одноуровневая память
Прежде чем погрузиться внутрь одноуровневой памяти, давайте попытаемся осмыслить общую картину, рассмотрев ее концепции и компоненты. Затем обсудим, почему одноуровневая память столь важна для AS/400 и разберем некоторые детали ее работы, взяв в качестве примера программу, выполняющую последовательное чтение индексированного файла базы данных (READ на ЯВУ или FETCH в SQL). В рамках этого примера мы разберем использование нескольких объектов: программы, индекса, курсора, области данных и др. Некоторые из них находятся в памяти, а некоторые нет.
Начнем с краткого обзора адресации этих и любых других объектов. Над MI нет различий между памятью и диском (или другим вспомогательным хранилищем). OS/ 400 работает только с объектами, их именами и открытым содержимым. MI работает со своими объектами – декомпозицией объектов OS/400 – с помощью их идентификаторов (указателей). Других способов задания объектов на уровне MI нет.
Программы, курсоры, области данных и другие объекты могут быть найдены простым указанием их имени. Чтобы использовать объект как ресурс, исполняющейся программе нужно «знать» только его имя и тип (как Вы помните, указание библиотеки необязательно, так как если она не задана, то будет просматриваться список библиотек). Имя объекта сразу же отображается в виртуальный адрес. Виртуальные адреса всех поименованных объектов находятся в библиотеках. Данный адрес помещается в указатель в процессе операции разрешения (описывалась в главе 5). Таким образом, системный указатель содержит виртуальный адрес заголовка объекта, который, в свою очередь, может содержать указатели на другие части данного объекта OS/400 и связанных с ним объектов MI.
Для обращения к данным объекта, или для исполнения команд программы, они должны быть перенесены в память. В нашем примере последовательного чтения базы данных, фрагмент программы, содержащий команды на выполнение чтения, должен быть перенесен с диска в память, прежде чем команды исполнятся. Такой перенос с диска в память происходит ниже уровня MI, так как MI не различает диск и память.
Можно считать, что все объекты находятся в памяти. То, что размер физической памяти слишком мал для хранения всех объектов – ограничение современных аппаратных технологий. Когда требуется фрагмент объекта, которого в памяти нет, этот отсутствующий фрагмент переносится и замещает некоторую неиспользуемую часть памяти. Можно также для наглядности представлять себе память как набор экранов, используемых для просмотра огромного пространства, содержащего все объекты. Процесс переноса страниц в память и из нее тогда будет выглядеть как изменения изображений на одном или нескольких экранах.
Рисунок 8.1 иллюстрирует отображение объектов на виртуальные адреса ниже уровня MI. Физическое расположение разных фрагментов объектов здесь показано на примере двух: программы и пространства. Для простоты восприятия даны очень маленькие объекты, но концепция неизменна для объектов любого размера. Кроме того, на рисунке изображены два основных компонента управления памятью SLIC: управление вспомогательной памятью и управление основной памятью. Вкратце, их функции таковы: управление вспомогательной памятью распределяет виртуальным адресам объекта дисковое пространство, а управление основной памятью руководит перемещениями между дисковой и основной памятью.
Рисунок 8.1. Объекты в одноуровневом хранилище
На рисунке видно, что память состоит из соответствующих экранам из предыдущей аналогии, страничных фреймов (их называют так, потому что они содержат страницы), размер которых на машинах IMPI был равен 512 байтам, а теперь на PowerPC – 4 КБ (4 096 байтов). Объект на диске разделен на страницы того же размера, что и страницы памяти. Со страницей диска связан виртуальный адрес объекта. Он может обозначать любой байт в пространстве объекта, и следовательно, указывать в середину страницы. Большой объект может занимать несколько страниц, но система спроектирована так, что на странице не могут содержаться части более чем одного объекта.
Удивительно, но мне часто задают вопрос: «Для чего нужна виртуальная адресация до байта? Почему не адресовать просто объекты, как это делают команды MI?». Для полного ответа, необходимо начать с того, что AS/400 (как CISC, так и RISC-мо-дели) работают на самых обычных процессорах, получающих команды и данные из памяти. Механизм адресации процессора, показанный на рисунке 8.1, ничего «не знает» об объектах. Системные объекты MI находятся в памяти, и процессор использует побайтную адресацию для получения информации о них: записей файла, команд программы и т. д. Процессор IMPI использует для доступа к памяти 48-разрядный виртуальный адрес, транслируя его в реальный; процессор PowerPC – эффективные адреса, которые транслирует сначала в виртуальные, а потом в реальные адреса. В обоих процессорах адреса следующей команды и используемых данных хранятся в аппаратных регистрах.
Страница, перенесенная в память одним процессом (заданием), становится доступной любому другому. Множество заданий могут использовать команды программ совместно. Записи, считанные из базы данных последними, вероятно, все еще находятся в памяти. Объем дискового ввода-вывода значительно сокращается при многократном считывании одних и тех же записей. Предположим, что в нашем примере чтения базы данных используется индекс, разделяемый с другими пользователями системы. Если этот индекс был недавно считан одним из них, то часть или весь индекс, вероятно, все еще в памяти, и не нужно ждать выборки страниц индекса с диска. В обычной системе с более ограниченными возможностями разделения данных в память пришлось бы перенести новую копию индекса, несмотря на то, что одна там уже есть.
Получив виртуальный адрес, аппаратура сначала проверяет, не присутствует ли уже соответствующая страница в памяти. Если она там, то она и используется. Если нет, то отсутствующая страница будет считана с диска.
Трансляция виртуального адреса в реальный состоит в поиске в страничной таблице, расположенной в памяти, страничного фрейма, соответствующего виртуальному адресу. Аппаратный просмотр таблицы страниц в поисках группы записей PTEG (page table entry group) ведется с помощью алгоритма хеширования (описывается далее в этой главе). Каждая PTEG содержит восемь записей таблицы страниц, которые просматриваются по одной. Если заданная страница не найдена, то происходит страничная ошибка – аппаратное прерывание, по которому управление основной памятью SLIC определяет дисковый адрес, соответствующий виртуальному, и обращается к процессору ввода-вывода с просьбой прочитать страницу с диска.
Для ускорения поиска страниц, использовавшихся последними, процессор содержит набор регистров, называемый справочным буфером трансляции TLB (translation lookaside buffer), где запоминаются последние использовавшиеся записи таблицы страниц. Так как регистры TLB встроены в процессор, то загрузка из памяти, где расположена таблица страниц, при обращении виртуальному адресу недавно использованной страницы, не требуется. Если же виртуального адреса в TLB нет, то на следующей стадии процесса трансляции аппаратура обращается к таблице страниц.
Процессоры PowerPC, используемые в последних моделях AS/400, могут также работать в режиме неактивных тегов. Данный режим никогда не используется OS/400, но для полноты описания поговорим и о его адресации. Итак, если процессор PowerPC работает в режиме неактивных тегов, то аппаратура сначала обращается к справочному буферу сегментов SLB (segment lookaside buffer) – другому набору регистров микросхемы процессора, содержащему использованные последними фрагменты таблицы сегментов. Если совпадения в регистрах SLB не найдено, то аппаратура обращается к таблице сегментов в памяти перед тем, как обратиться к регистрам TLB и таблице страниц. Другими словами, в режиме неактивных тегов процесс трансляции адресов трехшаговый: эффективный – виртуальный – реальный.
Для сообщения процессору ввода-вывода о страничной ошибке SLIC использует адрес другого типа, называемый адресом прямого сохранения (direct store address). Такие адреса употребляются при взаимодействии с любым внешним устройством. Они начинаются с шестнадцатиричного значения 801. Часть адреса прямого сохранения передается непосредственно процессу, управляющему внешним устройством.
Когда страница переносится с диска, она замещает в памяти страницу, которая давно не использовалась. С любой страницей связаны специальные разряды, которые устанавливаются при каждом обращении к ней. Измененные страницы также помечаются, чтобы в случае замещения в памяти они были записаны обратно на диск.
Память содержит команды программ, данные и указатели. Под данными здесь понимается все, что не является исполняемой командой или указателем: все объекты OS/400, кроме объектов-программ, а также неисполняемые части объектов-программ. Сравните этот подход с подходом команды «WRSYSSTS» (Work With System Status), которая различает только страничные ошибки, связанные с работой базы данных, и все остальные. Страничные ошибки базы данных относятся только к физическим и логическим файлам. Прочие страничные ошибки, такие как ошибки для программы, курсора или любого пространства из нашего примера последовательного чтения относятся ко все остальным.
Ранее мы рассмотрели страничные ошибки. Для считывания страницы с диска не обязательно ждать, пока такая ошибка произойдет. Любой компонент SLIC или любая транслированная программа MI может запросить у управления главной памятью SLIC явный перенос (считывание) в память диапазона виртуальных страниц (одной или более). Функционально явный перенос страниц в память не нужен, так как требуемые страницы всегда будут перенесены по страничной ошибке, но тогда процесс, вызывавший ее, ожидает завершения чтения с диска. Запрос на операцию переноса до того, как страницы фактически потребуются, позволяет выполнять операции дискового чтения параллельно с другой обработкой. Таким образом, явные переносы снижают временные затраты и повышают производительность.
Возможно также явное создание очищенных страничных фреймов в памяти. Запрос на очистку, переданный управлению главной памятью, расписывает один или несколько страничных фреймов в памяти двоичными нулями. Эта операция полезна, например, в тех случаях, когда буфер заполняется новыми данными и текущее содержимое диска Вас не интересует. Вместо чтения страниц буфера, как в результате отдельных страничных ошибок, так и с помощью переноса, операция очистки позволяет обнулить страничные фреймы без обращения к диску.
При запросе на перенос или очистку может быть выбран параметр обмена. Он задает диапазон виртуальных страниц, которые компонент управления главной памятью SLIC может использовать для замещения вместо выбранных по нормальному алгоритму. Обмен применяется для того, чтобы не удалять из памяти страницы, к которым постоянно обращаются, и не заменять их страницами, которые вряд ли будут нужны больше одного раза. Обмен полезен и в том случае, когда значительное число страниц переносится в небольшую память или небольшой пул памяти. (Память часто разделяется на несколько пулов меньшего размера и вся подкачка страниц для данного процесса выполнятся в одном пуле. Подробнее о пулах – в главе 9.).
В запросе на перенос или очистку также можно указать, что одну или несколько страниц следует зафиксировать в памяти. Фиксированная страница становится резидентной и не будет удалена из памяти или записана обратно на диск вплоть до отмены этого распоряжения. Некоторые структуры данных SLIC, такие как элементы диспетчеризации, используемые в управлении процессами, всегда резидентные. Для ввода-вывода на виртуальную страницу и обратно, они должна быть зафиксированы, так как при перемещении данных по шине ввода-вывода используется реальный адрес фрейма страницы. Режим фиксации снимается отдельным запросом к управлению памятью.
Дополняет перенос и очистку страниц возможность сбросить (переписать) одну или нескольких страниц на диск. Сброс имеет смысл только тогда, когда страница в памяти были изменена, то есть копия страницы на диске неактуальна. В отличие от переноса и очистки, которые не являются функционально необходимыми (эти задачи выполнит обработка страничной ошибки), сброс иногда необходим, например, при журналировании базы данных. В этом случае компонент базы данных в SLIC должен гарантировать, что записи журнала в журнальном пространстве записаны на диск, причем он обязан использовать функцию сброса, не дожидаясь, пока страницы журнального пространства будут записаны на диск в результате страничных ошибок. Кроме того, сбросом можно снять фиксацию в памяти одной или нескольких страниц.
Наконец, страничные фреймы могут быть удалены из памяти без записи обратно на диск. Функциональных причин для удаления страниц нет, но это полезно, так как устраняет последующие операции записи на диск, например, если буфер памяти был опустошен и данные в нем больше не нужны.
Процессор PowerPC имеет отдельные кэши данных и команд, играющие роль буфера между основной памятью и процессором. По сути дела кэши – это регистры на микросхеме процессора, обеспечивающие быстрый доступ к недавно использовавшимся командам или данным. В AS/400 часть виртуальных адресов используется для доступа к кэшам.
Указатели должны быть защищены от повреждений. Программа пользователя, работающая на уровне MI, вполне способна изменить указатель, так как указатели хранятся в ассоциированном пространстве объектов MI вместе с другими структурами, к которым программа должна иметь доступ. Значения указателей также могут быть разрушены физическими явлениями, такими как флуктуации напряжения. Если указатель изменен «незаконно» (то есть не процедурой SLIC с помощью команды, недоступной непосредственно в MI), а каким-либо иным способом, то аппаратура сбрасывает разряд тега, делая тем самым указатель недействительным.
Все временные и постоянные объекты подлежат страничному обмену (переносу их на диск и обратно в память по мере необходимости). Некоторые структуры (таблица страниц) и программы SLIC не откачиваются; они загружаются в процессе IPL и должны находиться в памяти постоянно. Их адреса не требуют трансляции, так как виртуальные адреса подобных структур или команд – реальные адреса памяти. Такого рода адреса всегда начинаются с шестнадцатиричного 800.
Теперь, после краткого обзора, перейдем к детальному рассмотрению этих тем: разберем подробно влияние одноуровневой памяти на производительность, работу указателей, трансляцию адреса, и, наконец, управление дисками. Внимание! Для индикации «горячих» тем, будет использоваться «перечная» система.