Одноуровневая память
Сегодня в компьютерной индустрии модны длинные адреса (в данном случае, "длинный" означает больше 32 разрядов). Практически все производители аппаратуры и ОС начали использовать их в своих продуктах, а в качестве стандарта для следующего поколения предусматривают 64 разряда. Переход на адреса большего размера стимулируется новыми приложениями, такими как хранилища данных, а также снижением цен на основную память. Заказчики отмечают значительное повышение производительности при использовании памяти большого размера, и размеры памяти, измеряемые гигабайтами, становятся обычным делом. 32-разрядный адрес, способный поддерживать размеры памяти только до 4 ГБ, быстро устаревает. Довольно долго процессоры AS/400 и их предшественники — процессоры System/38 — использова ли 48-разрядные адреса. С переходом на RISC-процессоры размер адреса возрос до 64 разрядов.
Одноуровневая память с большими адресами — вероятно, один из самых известных компонентов AS/400, и редко какая презентация обходится без упоминания о ней. Это даже странно — ведь одноуровневая память не видима никому и ничему выше уровня MI: ни OS/400, ни прикладным программам, ни даже компиляторам. Она доступна только SLIC, а MI работает с объектами, используя для ссылок на них имена. Пространство — эквивалент памяти на уровне MI, но пространство не очень на поминает одноуровневую память.
Программы, и прикладные, и системные адресуют объекты при помощи 16-байтовых указателей; которые точнее было бы называть 128-разрядными (их используют все прикладные программы с момента появления System/38 в 1978 году). Но не все разряды этого указателя используются, поэтому AS/400 обычно не называют 128-разрядным компьютером. Указатель содержит 64-разрядный адрес одноуровневой памяти, а также несколько разрядов дескриптора и неиспользуемые разряды, зарезервированные для будущих расширений.
Возможно, нам следует называть AS/400 128-разрядной системой — согласитесь, это было бы неплохой рекламой. Ведь называет же Digital свой процессор Alpha 64-разрядным, хотя он реализует лишь 41-разрядные адреса! HP также не использует для адреса все 64 разряда в своем процессоре PA RISC 2.0. И все же, я полагаю, мы лучше будем пока говорить о 64 разрядах — по крайней мере, до тех пор, пока до уровня IBM не подтянутся остальные. Кроме того, 64 разряда уже и так дают очень большое адресное пространство.
"Но насколько большое?" — спросите Вы.
Сколько байтов адресуют 64 разряда
Ответ: 16 экзабайтов, что равно примерно 18,4 квинтиллионам байтов (или точнее 18 446 744 073 709 551 616 байтов).
Ричард Рубин, чьи замечания чрезвычайно помогли в работе над этой кни гой, напомнил мне историю, рассказанную Джорджем Гамовым (George Gamow) в книге " One, Two, Three, Infinity ". Однажды индийский шах Ширхам пожелал вознаградить своего великого визиря Сисса Бен Дахира за изобретение шахмат. Визирь попросил шаха положить на первую клетку шахматной доски одно зерно пшеницы, на вторую — два, на третью — четыре, на четвертую — восемь и так далее, удваивая число на каждой клетке, пока все 64 клетки не будут заполнены. Общее число зерен должно было бы составить 264–1. Гамов подсчитал, что если бушель1Американский бушель равен примерно 35,2 литра. — Прим. консультанта. пшеницы содержит 5 миллионов зерен, то для покрытия всей доски потребовалось бы 4 триллиона бушелей. Когда Гамов писал свою книгу в 1946 году, мировое производство пшеницы составляло 2 миллиарда бушелей в год. При сохранении производства на том же уровне, всему миру потребовалось бы две тысячи лет, чтобы вырастить требуемое количество зерен.
Для тех, кто предпочитает аналогию с миллиметрами, 18 квинтиллионов — это примерно вдвое больше числа миллиметров в световом годе, и всего лишь немногим меньше половины расстояния до Альфы Центавра (ближайшей к Солнечной системе звезде). Ясно, что если мы начнем измерять астрономические расстояния в миллиметрах, то нам потребуется более 64 разрядов. А 128-разрядный указатель дает нам...Так что какие бы аналогии мы не проводили, и как бы себе все это не представляли, 64-разрядная адресация предоставляет огромные возможности.
Виртуальная память
Одноуровневая память AS/400 получила свое имя в честь первопроходцев разработки виртуальной памяти в 60-х годах. Чтобы понять происхождение этого термина, необходимо углубиться в историю.
Впервые виртуальная память появилась в компьютере Atlas, созданном в 1961 в английском городе Манчестере (Manchester). В те годы для изготовления памяти использовалась очень дорогостоящая технология магнитных сердечников. Большим программам требовалось много памяти, зачастую больше, чем было на компьютере. Чтобы программа могла поместиться в памяти, приходилось разбивать ее на малые фрагменты и хранить на магнитных дисках или барабанах.
Магнитные барабаны были популярны в начале 60х годов. Барабан похож на жесткий диск, но у него по одной головке чтения/записи на каждую дорожку. В то время барабаны обеспечивали более высокую производительность по сравнению с дисками, так как исключалось время позиционирования головки на дорожку. С сокращением времени позиционирования барабаны вышли из употребления.
При разбиении больших программ на малые фрагменты управление памятью требовало от программиста больших усилий. Если фрагмент программы, который должен был исполняться, находился вне памяти, то программист вставлял команды считывания этого фрагмента в память с диска или барабана. Фрагменты программы назывались оверлеями (overlays), и значительная часть программирования заключалась в создании и управлении ими. Виртуальная память смогла устранить эту проблему. Память увеличилась, и программисты могли больше не беспокоиться о том, поместится ли в нее программа. Управление перемещением данных и программ в большой виртуальной памяти взяла на себя ОС.
В 1962 году Т. Д. Килбурн (T.D. Kilburn) с соавторами написал свою статью, посвя щенную системе памяти компьютера Atlas. В статье были такие слова: "... Система представляет программисту комбинацию память-барабан в виде одноуровневой памяти. Необходимое перемещение данных выполняется автоматически"2T.D. Kilburn, B.G. Edwards, M.J. Lanigan, F.H. Sumner. Onelevel Storage System./IRE Transactions on Electronic Computers. 1962. April..
Виртуальная память для систем разделения времени
В связи с появлением в конце 60х годов систем разделения времени — раннего этапа эволюции мультипрограммных ОС — многие производители компьютеров приняли виртуальную память на вооружение. При мультипрограммировании системная память разделена на несколько порций, в каждой из которых находится некоторая программа. Пока одна из программ ожидает завершения операции вводавывода, другая может использовать процессор. Если в памяти находится достаточное количество программ, то можно обеспечить постоянную загруженность процессора. Мультипрограммные ОС занимались тогда преимущественно пакетной обработкой.
Разделение времени — это разновидность мультипрограммирования, когда у каждого пользователя есть подключенный к компьютеру терминал. Так как при этом пользователи интерактивны (то есть программа управляется командами пользователя за терминалом), то на "раздумья" пользователей уходит какоето время. Соответственно снижается загрузка процессора. Компьютер такого типа поддерживает больше пользователей, так что в памяти одновременно находится довольно много фрагментов программ. Интерактивным пользователям требуется быстрое время отклика, так что эффективное управление множеством фрагментов программ критически важно. Именно его и должна была обеспечить виртуальная память.
В основе систем разделения времени лежала возможность аренды времени центрального компьютера отдельными пользователями из разных организаций. Такой подход был популярен, так как большинство малых фирм не могли позволить себе собственный компьютер. Разделение времени предоставляло им ресурсы большого компьютера за часть цены. Так как пользователи компьютера представляли разные организации, совместное использование информации ими не требовалось.
Поддерживая разделение времени, системы виртуальной памяти предоставляли каждому пользователю отдельное адресное пространство. Адресные пространства разных пользователей были изолированы друг от друга, что в определенной степени обеспечивало защиту. При переключении ресурсов компьютера на выполнение программы другого пользователя использовалось новое адресное пространство. Такая операция называлась переключением процессов, где процесс рассматривался как единица работы в системе, выполняемая для пользователя.
В прошлом переключение процессов было связано с большими накладными расходами. Нужно было изменить таблицы памяти, очистить регистры и загрузить новые данные. Выполнение всех этих действий требовало большого числа команд процессора, и явно чрезмерных затрат времени. Тогда, в конце 60х, многие искали способы упростить эту операцию и повысить ее эффективность3Идея виртуальной памяти заворожила тогда и меня, и я избрал ее в качестве темы своей диссертации в Университете штата Айова. Я недоумевал, как производители компьютеров, включая IBM, смогли "втиснуть" такую простую и элегантную идею в безумно сложные структуры. В конце концов, поиск такого решения виртуальной памяти, которое не требовало бы огромных накладных расходов и обеспечивало бы высокую производительность, привел к созданию System/38..
К сожалению, разработчики систем разделения времени решили вынести файловую систему за пределы виртуальной памяти. Они создали два места хранения данных и программ: виртуальную память и файловую систему. В подобной архитектуре данные и программы могут использоваться или изменяться, только если находятся в виртуальной памяти. То есть, прежде чем чтолибо сделать, данные и программы нужно переместить в виртуальную память.
Менеджер файлов обычной системы поддерживает каталог, связывающий имена файлов с местоположением на диске данных, которые в них содержатся. Менеджер файлов предоставляет некий интерфейс, позволяющий программе открыть файл. Затем данные копируются в буферы памяти, обычно являющиеся частью виртуальной памяти. После этого данные могут использоваться и обрабатываться. Когда программа завершает работу с данными, выполняется операция закрытия, переносящая данные из виртуальной памяти обратно в файловую систему.
Простой и знакомый большинству из нас пример подобного механизма — использование текстового процессора на ПК. Сначала пользователь открывает файл, содержащий нужный документ, а затем наблюдает мигание индикатора жесткого диска, пока документ считывается в память. На самом деле, документ сначала переносится в виртуальную память, а затем частично — в реальную память. Когдато раньше, при конфигурировании ОС нашего ПК, мы определяли размер места на жестком диске, зарезервированный для виртуальной памяти. В мире ПК это пространство иногда называется файлом подкачки. Прокручивая текст на экране, пользователь снова видит, как мигает индикатор жесткого диска. По мере необходимости, новые фрагменты документа считываются в память из зарезервированного пространства на диске.
Операция открытия файла создает копию документа. Оригинал же попрежнему находится на жестком диске в неизменном виде. Копия располагается в дисковом пространстве, зарезервированном под виртуальную память. Менеджер виртуальной памяти и ОС автоматически переносят фрагменты документа по мере необходимости из зарезервированной дисковой области в память, а когда надобность в них отпадает — возвращают обратно. Фактически, если учесть копию в памяти, некоторые фрагменты документа существуют в трех копиях.
Когда пользователь заканчивает редактирование и сохраняет документ, текстовый процессор запрашивает, сохранить ли изменения. Другими словами, нужно ли записать обновленную в виртуальной памяти копию обратно в файл на диске для постоянного хранения. Если ответ утвердительный, то копия из виртуальной памяти замещает копию на диске.
Одноуровневая виртуальная память
В только что описанной реализации виртуальной памяти программист имеет дело с двумя уровнями хранилища: файловая система и виртуальная память разделены. Двухуровневая система хранения вызывает дополнительные накладные расходы. Открытие файла связано с записью на диск в файлы подкачки, а закрытие — требует записи обратно на место постоянного хранения.
Сам собой напрашивается альтернативный вариант — работать только с одной копией файла. Ведь если нет двух отдельных копий, то не нужно резервировать пространство на диске для файла подкачки. При таком подходе вся файловая система становится частью виртуальной памяти. Менеджер файлов попрежнему ведет справочник, но теперь он связывает имя файла с местом в памяти, где находятся данные файла. При открытии и закрытии файла не требуется копировать весь файл из его постоянной области хранения на диске. В буфер памяти копируется только та порция (или запись) с которой пользователь в данный момент работает. Часто говорят и так: файлы всегда используются там же, где хранятся. Все это позволяет повысить общую производительность системы.
Одноуровневая память — это именно то, что ставили своей целью создатели первой виртуальной памяти, и именно эта модель была реализована в System/38. В честь первооткрывателей мы решили назвать нашу виртуальную память одноуровневой памятью.
Одноуровневая память — это именно то, что ставили своей целью создатели первой виртуальной памяти, и именно эта модель была реализована в System/38. В честь первооткрывателей мы решили назвать нашу виртуальную память одноуровневой памятью.
И двухуровневая виртуальная память, и одноуровневая используются как буфер. Процессоры могут работать только с данными в памяти, но не на диске. Отличие одноуровневой схемы в том, что память в ней — кэш для всего дискового пространства, а не только для зарезервированной области диска. Кроме того, после изменения файла одним пользователем, это изменение немедленно становится видимым всем остальным, работающим с тем же файлом.
Недостаток одноуровневой памяти — большой размер адреса. Адрес должен быть достаточно велик, чтобы покрывать все подключенное к системе дисковое пространство. Возьмем 32-разрядный адрес, используемый во многих современных системах. С его помощью можно адресовать до 4 ГБ, что совершенно недостаточно для адресации всего дискового пространства даже на большом ПК. Таким образом, обычные системы просто вынуждены копировать дисковые данные в свои относительно небольшие виртуальные памяти и обратно.
Чтобы устранить это ограничение, в System/38 и первые модели AS/400 был включен 48-разрядный адрес. Теперь AS/400 использует 64разрядный адрес и для будущих расширений предусмотрены дополнительные разряды адреса. Хоть все это и связано с аппаратными затратами, последние вполне компенсируются возможностями по совместному использованию данных и ростом производительности.
Постоянная виртуальная память
Размер адреса AS/400 значительно превышает необходимый для покрытия всего дискового пространства. Причина такого положения — другая характеристика одноуровневой памяти, называемая постоянством (persistence). Мы уже говорили об этом в "Объекты" , посвященной объектам. Объект, обладающий постоянством, остается в памяти системы вечно, даже после своего разрушения, и виртуальное адресное пространство такого постоянного объекта никогда не используется повторно. При разрушении постоянного объекта освобождается все занятое им дисковое пространство, за исключением заголовков. Освобожденное дисковое пространство затем используется для других объектов.
То, что виртуальное адресное пространство повторно не используется, устраняет многие проблемы защиты и целостности. Если постоянный объект разрушен и его адресное пространство использовано повторно другим объектом, то любой, у кого был разрешенный указатель на старый объект, сможет адресовать новый объект. Так как указатели могут храниться в памяти где угодно, то большинство схем "сборки мусора" для поиска указателей уничтоженных объектов слишком сложны. В 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 адресовать любой сегмент всего адресного пространства, а не только подмножество сегментов, как в модели адресации относительно сегмента. Программа может обращаться ко всей виртуальной памяти, а сама виртуальная память может быть разделяемой без каких-либо накладных расходов.