ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.01.2021

Просмотров: 157

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

5


Лекция 15


6. Уровень операционной системы


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

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

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

В данном курсе мы лишь кратко опишем уровень операционной системы, при этом сосредоточившись всего на трех важных особеннос­тях. Первая из них - виртуальная память, которая исполь­зуется многими операционными системами. Она позволяет создать впечатление, что у машины больше памяти, чем есть фактически. Вторая особенность - файлы ввода-вывода. Третья - параллель­ная обработка (как несколько процессов могут выполняться, обмениваться инфор­мацией и синхронизироваться). Под процессом можно понимать ра­ботающую программу и всю информацию о ее состоянии (о памяти, регистрах, счетчике команд, вводе-выводе и т. д.). После обсуждения этих основных понятий мы рассмотрим, как они реализуются в операционных системах двух машин из трех наших примеров: Pentium II (Windows NT) и UltraSPARC II (UNIX). Поскольку picoJava II обычно используется для встроенных систем, у этой машины нет операционной системы.


6.1. Виртуальная память


В первых компьютерах память была мала по объему и дорого сто­ила. IBM-650, ведущий компьютер конца 50-х годов, содержал 2000 слов памяти. Один из первых компиляторов (ALGOL) был написан для компьютера с размером памяти 1024 слова. На компьютере PDP-1 работала система с разделением времени, при этом общий размер памяти составлял 4096 18-битных слов.

В те времена программы разрабатывались с учетом недостатка памяти, зачастую в ущерб быстродействию. Одним из решений проблемы было использование вспомогатель­ной памяти (например, диска). Программист делил программу на несколько час­тей (оверлеев), которые поочередно загружались в память для выполнения, и управлял этим процессом сам программист. В 1961 году исследователями из Манчестера был предложен метод автоматического выполнения процесса наложения, при котором программист мог вообще не знать о нем. Этот метод, который сейчас называется виртуальной памятью, освобождал про­граммиста от большого количества нудной работы. К началу 70-х годов вир­туальная память появилась в большинстве компьютеров. Современные компьютеры, в том числе Pentium и UltraSPARC, со­держат сложные системы виртуальной памяти.



6.1.1. Страничная организация памяти


В основе механизма виртуальной памяти лежит разделение понятий адресного пространства и адресов памяти. Рассмотрим в качестве иллюстрации старый компью­тер с 16-битным полем адреса в командах и 4096 словами памяти. Программа на нем теоретически могла обращаться к 65536 словам памяти (адреса 16-битные, 216=65536). Это зависит только от количества разрядов адреса и не связа­но с числом реально доступных слов. Логическое адресное пространство такого компьютера состоит из чисел 0, 1, 2,..., 65535, однако в действительности (физически) компьютер имеет слов памяти гораздо меньше.

До изобретения виртуальной памяти проводилось жесткое разли­чие между адресами < 4096, и адресами >= 4096. Эти две части рассматривались соответственно как полезное и бесполезное адресные пространства. Ника­кого различия между адресным пространством и адресами памяти не проводилось, между ними подразумевалось взаимнооднозначное соответствие.

Идея разделения понятий адресного пространства и адресов памяти состоит в неоднозначности этого соответствия. Если всегда можно получить прямой доступ к 4096 физическим словам памяти, то это не значит, что они обязаны соответствовать логическим адресам памяти от 0 до 4095. Например, можно сообщить системе, что при обра­щении к логическому (виртуальному) адресу 4096 должно использоваться слово из памяти с адресом 0, при обра­щении к адресу 4097 - слово из памяти с адресом 1 и т. д. Другими словами, определяется отобра­жение адресного пространства в физические адреса памяти. При обращении к адресу из другой группы текущее содержимое физической памяти сохраняется на диске, и в память загружается нужная часть виртуальной памяти (действует другое отображение).

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

Программист может разрабатывать программы ничего не зная о виртуальной памяти. Создается впечатление, что объем памяти компьютера до­статочно велик. Такой механизм называется прозрачным.


6.1.2. Реализация страничной памяти


Для виртуальной памяти требуется диск достаточного объема. Виртуальное адресное пространство разбивается на страницы равного размера, обычно от 512 байт до 64 Кбайт, иногда встречается 4 Мбайт. Размер страни­цы является степенью двойки. Физическое адресное пространство также разбивается на части равного размера таким образом, чтобы каждая такая часть основной памяти вмещала одну страницу (возможно, с некоторой служебной информацией). Эти части основной памяти на­зываются страничными кадрами.


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

Компьютер с виртуальной памятью обычно содержит устрой­ство для отображения виртуальных адресов в физические, которое называется контроллером управления памятью (MMU - Memory Management Unit). MMU может находиться на самой микросхеме процессора или на отдель­ной рядом с ним. Когда в MMU поступает вир­туальный адрес, он разделяет его на составные части (например, 20-битный номер виртуальной страни­цы и 12-битное смещение внутри этой страницы). Номер страницы используется в качестве индекса в таблице страниц. Сначала MMU проверяет, находится ли нужная стра­ница в текущий момент в физической памяти (проверяет бит присутствия в соответствующем элементе таблицы страниц). Далее из таблицы нужно взять адрес страничного кадра и скопировать его в старшие разряды выходного регистра. Младшие разряды виртуально­го адреса (смещение в странице) копируются в младшие биты выходного регистра. Наконец, полученный физический адрес отправляется в кэш-память или ос­новную память для поиска.


6.1.3. Политика загрузки и замещения страниц


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

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

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

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


По одному из алгоритмов удаляется та страница, которая использовалась наи­более давно. Вероятность ее нахождения в текущем рабочем множе­стве мала. Этот алгоритм называется LRU (Least Recently Used - алго­ритм удаления наиболее давно использовавшихся элементов). Существует и другой алгоритм - FIFO (First-in First-out - первым поступил, первым выводится). Он удаляет ту страницу, которая раньше всех загружалась, в независимости от давности использования.

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

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


6.1.4. Размер страниц и фрагментация


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

При размере страницы в n байтов среднее неиспользованное про­странство в последних страницах составляет n/2 байтов. С этой точки зрения выгоднее использовать страницы небольшого размера. Более того, рабочее множество будет состоять из большего количества страниц. В этом случае оно может охватить большее количество несвязанных областей, что снижает вероятность пробуксовки.

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

Таким образом, существует проблема компромисса при выборе размера страницы виртуальной памяти.


6.1.5. Сегментация


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


Несколько независимых виртуальных адресных пространств называются сегментами. Каждый сегмент состоит из линейной последо­вательности адресов. Длина каждого сегмента мо­жет быть произвольной. Более того, длина сег­мента может меняться во время выполнения программы. Разные сегменты могут увеличиваться или уменьшаться не влияя друг на друга. Так если стеку в определенном сегменте понадобится больше адресного пространства, он может получить его без проблем. Таким образом, память становится двумерной. Чтобы определить адрес, программа должна вы­давать номер сегмента и адрес внутри сегмента.

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

Если каждая процедура занимает отдельный сегмент, в котором первый адрес = 0, то компоновка отдельно компилируемых процедур существенно упрощается. При изменении и перекомпиляции процедур другие менять не нужно даже на этапе редактирования связей, т.к. точки входа не меняются. Этот же принцип облегчает разделение общих процедур или данных между несколь­кими параллельными программами.

Разные сегменты виртуальной памяти могут иметь разные виды защиты. Например, сегмент с про­цедурой можно определить как “только для выполнения”, запретив тем самым не только запись, но и считывание из него. Для массива данных разрешается только чтение и запись, но не выполнение и т. д. Такая защита помогает об­наружить ошибки в программе.


6.1.6. Реализация сегментации


Сегментацию можно реализовать одним из двух способов - подкачка (“чистая сегментация”) и разби­ение на страницы. Подкачка сегментов очень похожа на вызов страниц по требованию: сегменты загружаются и удаляются только в случае необходимости. В каждый момент в физической памяти находится некоторый набор сегментов. Если происходит обращение к отсутствующему сегменту, то он загружается в память. Если для него нет места в памяти, один или несколько сегментов нужно удалить, при необходимости записав на диск. Тем не менее сегментация существенно отличается от разбиения на страницы тем, что размер страниц фиксирован, а сегментов - нет. В связи с этим возможна внешняя фрагментация (неиспользованное пространство попадает не в сегменты, а в промежутки между ними. Иногда внешнюю фраг­ментацию называют поклеточной разбивкой. Для ее устранения периодически или по необходимости может запускаться процесс дефрагментации (уплотнения памяти), что снижает общую производительность.

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


Смотрите также файлы