Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Танненбаум Е. Архітектура компютера [pdf]

.pdf
Скачиваний:
103
Добавлен:
02.05.2014
Размер:
5.59 Mб
Скачать

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

443

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

-15-битныйадреспамяти

Виртуальная

страница

Таблица

страниц

Бит присутствия

1 110 --

20-битнаявиртуальнаястраница— И - * -12-битноесмещение-

32-битный виртуальныйадрес

Выходной

регистр

Входной

регистр

Рис. 6.4. Формированиеадресаосновной памяти из адреса виртуальной памяти

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

регистра. Затем полученный 15-битный адрес отправляется в кэш-память новную память для поиска.

На рисунке 6.5 показано возможное отображение виртуальных страниц ческие страничные кадры. Виртуальная страница 0 находится в страничном Виртуальная страница 1 находится в страничном кадре 0. Виртуальной стр нет в основной памяти. Виртуальная страница 3 находится в страничном Виртуальной страницы 4 нет в основной памяти. Виртуальная страница дится в страничном кадре 6 и т. д.

Таблица страниц

 

 

Виртуальная

Страничный

 

 

страница

 

кадр

 

 

 

; '.г

 

s

 

 

15

0

0

 

 

 

14

1

4

\

 

 

13

0

0

 

 

 

12

0

0

 

 

 

11

1

5

N

 

 

10

0

0

 

 

 

9

0

0

 

Страничны

8

1

3

-

Основная память

кадр

 

7

0

0

 

Виртуальная страница 6

7

6

1

7

-

Виртуальная страница 5

6

5

1

6

-

Виртуальная страница 11

5

4

0

0

 

Виртуальная страница 14

4

3

1

2

-

Виртуальная страница 8

3

2

0

0

 

Виртуальная страница 3

2

 

 

1

1

0

-

Виртуальная страница 0

1

 

0

1

1

-

Виртуальная страница 1

0

 

\

1 = присутствует в основной памяти

0 = отсутствует в основной памяти

Рис. 6.5. Возможное отображение первых 16 виртуальных страниц в основную память, содержащую 8 страничных кадров

Вызовстраницпотребованию

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

445

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

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

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

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

Альтернативный подход основан на наблюдении, что большинство команд обращаются к адресному пространству не равномерно. Обычно большинство обращений относятся к небольшому числу страниц. При обращении к памяти можно вызвать команду, вызвать данные или сохранить данные. В каждый момент времени t существует набор страниц, которые использовались при последних к обращениях. Деннинг [29] назвал этот набор страниц рабочим множеством.

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

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

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

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

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

По одному из алгоритмов удаляется та страница, которая использова более давно, поскольку вероятность того, что она будет в текущем рабоче стве, очень мала. Этот алгоритм называется LRU (Least Recently Use ритм удаления наиболее давно использовавшихся элементов). Хотя этот работает достаточно хорошо, иногда возникают патологические ситуац описана одна из них.

Представьте себе программу, выполняющую огромный цикл, которы рается на девять виртуальных страниц, а в физической памяти место ес для восьми страниц. Когда программа перейдет к странице 7, в основно будут находиться страницы с 0 по 7 (табл. 6.1). Затем совершается поп звать команду из виртуальной страницы 8, что вызывает ошибку из-за о страницы. Нужно принять решение, какую страницу убрать. По алгори будет выбрана виртуальная страница 0, поскольку она использовалась ран Виртуальная страница 0 удаляется, а нужная виртуальная страница по на ее место (табл. 6.2).

Таблица 6 . 1 . Ситуация, в которой алгоритм LRU не действует (1) Виртуальная страница 7 Виртуальная страница 6 Виртуальная страница 5 Виртуальная страница 4 Виртуальная страница 3 Виртуальная страница 2 Виртуальная страница 1 ВиртуальнаястраницаО

Таблица 6.2. Ситуация, в которой алгоритм LRU не действует (2) Виртуальная страница 7 Виртуальная страница 6 Виртуальная страница 5

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

4 4

Таблица 6.3. Ситуация, в которой алгоритм LRU не действует (3) Виртуальная страница7 Виртуальнаястраница6 Виртуальнаястраница5 Виртуальная страница4 Виртуальнаястраница3 Виртуальная страница 2 ВиртуальнаястраницаО Виртуальная страница8

После выполнения команд из виртуальной страницы 8 программа возвращае ся к началу цикла, то есть к виртуальной странице 0. Этот шаг вызывает еще одн ошибку из-за отсутствия страницы. Только что выброшенную виртуальную стр ницу 0 приходится вызывать обратно. По алгоритму LRU удаляется страница (табл. 6.3). Через некоторое время программа пытается вызвать команду из ви туальной страницы 1, что опять вызывает ошибку. Затем вызывается страница и удаляется страница 2 и т. д.

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

Можно применять и другой алгоритм — FIFO (First-in First-out — первы поступил, первым выводится). FIFO удаляет ту страницу, которая раньше вс загружалась, независимо от того, когда в последний раз производилось обращен к этой странице. С каждым страничным кадром связан отдельный счетчик. Изн чально все счетчики установлены на 0.

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

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

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

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

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

Если пользовательская программа и данные время от времени заполня целое число страниц, то когда они находятся в памяти, свободного места там С другой стороны, если они не заполняют ровно целое число страниц, на п странице останется неиспользованное пространство. Например, если про данные занимают 26 000 байтов на машине с 4096 байтами на страницу, т 6 страниц будут заполнены целиком, что в сумме даст 6x4096=24 576 бай следняя страница будет содержать 26 000-24576=1424 байта. Поскольку странице имеется пространство для 4096 байтов, 2672 байта останутся с ми. Всякий раз, когда седьмая страница присутствует в памяти, эти бай занимать место в основной памяти, но при этом не будут выполнять никак ции. Эта проблема называется внутренней фрагментацией (поскольку н зованное пространство является внутренним по отношению к какой-то ст

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

Более того, маленькие страницы снижают эффективность пропускно ности диска. Поскольку перед началом передачи данных с диска приходи примерно 10 млс (поиск + время вращения), выгоднее совершать больш дачи. При скорости передачи данных 10 Мбайт в секунду передача 8 Кба ляет всего 0,7 млс (по сравнению с передачей 1 Кбайт).

Однако у маленьких страниц есть свои преимущества. Если рабочее м состоит из большого количества маленьких отделенных друг от друга виртуального адресного пространства, при маленьком размере страницы б возникать пробуксовка (режим интенсивной подкачки), чем при больш смотрим матрицу А 10 000x10 000, которая хранится в последовательны ныхсловах(А[1,1],А[2,1],А[ЗД]ит. д.). При такой записи элементы ряда

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

449

При размере страницы в 1 Кбайт для хранения всех страниц потребуется всего 10 Мбайт ОЗУ. При размере памяти в 32 Мбайт и размере страницы в 8 Кбайт программавойдет в режим интенсивной подкачки, а при размере страницы в 1 Кбайт этого не произойдет.

Сегментация

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

1.Таблица символов, которая содержит имена и атрибуты переменных.

2.Исходный текст, сохраняемый для распечатки.

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

4.Дерево, содержащее синтаксический анализ программы.

5.Стек, используемый для вызова процедур в компиляторе.

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

Виртуальное адресное пространство

Свободное•[

 

 

Адресное пространство,

Используемое Г

Стек

i

предназначенное

 

для стека вызовов

в данный момент

вызовов

 

 

 

 

 

 

 

Дерево

t

 

 

Таблица

 

 

 

констант

т

 

 

 

 

Исходный текст Т

Таблица

символов

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

4 5 0 Глава 6. Уровень операционной системы

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

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

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

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

Так как каждый сегмент основывает отдельное адресное пространств сегменты могут увеличиваться или уменьшаться независимо друг от д влияя друг на друга. Если стеку в определенном сегменте понадобилос адресного пространства (чтобы стек мог увеличиться), он может получит скольку в его адресном пространстве больше не во что «врезаться». Ест сегмент может переполниться, но это происходит редко, поскольку сегме большие. Чтобы определить адрес в двухмерной памяти, программа до давать номер сегмента и адрес внутри сегмента. На рис. 6.7 изображен тированная память.

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

20К

 

 

 

 

16К

 

 

 

 

12К

Таблица

 

 

 

 

 

 

 

символов

 

 

 

 

 

Исходный

 

Стек

 

 

 

 

текст

Таблица

Дерево

 

 

О

 

 

констант

 

 

 

 

 

 

Сегмент 0

Сегмент 1

Сегмент 2

Сегмент 3 Сегмент 4

Рис. 6.7. Сегментированная памятьпозволяетувеличивать

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

45 1

адрес — это адрес 0, то связывание процедур, которые компилируются отдельно, сильно упрощается. Когда все процедуры программы скомпилированы и связаны, при вызове процедуры из сегмента п для обращения к слову 0 будет использоваться адрес (п, 0).

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

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

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

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

Таблица 6.4. Сравнение страничной организации памяти и сегментации

Свойства

Страничная

Сегментация

 

организация памяти

 

Долженли программистзнатьобэтом?

Нет

Да

Сколько линейных адресных

1

Много

пространств имеется?

 

 

Можетли виртуальноеадресное пространство Да

Да

увеличиватьразмерпамяти?

 

 

4 5 2 Глава 6. Уровень операционной системы

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

Как реализуется сегментация

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

впамяти в данный момент. Если происходит обращение к сегменту, кото

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

Однако сегментация существенно отличается от разбиения на страни дующем: размер страниц фиксирован, а размер сегментов — нет. На р показан пример физической памяти, в которой изначально содержится тов. Посмотрим, что происходит, если сегмент 1 удаляется, а сегмент 7, меньше по размеру, помещается на его место. В результате получится к рация, изображенная на рис. 6.8, б. Между сегментом 7 и сегментом 2 ся неиспользованная область («дырка»). Затем сегмент 4 меняется на с (рис. 6.8, в), а сегмент 3 замещается сегментом 6 (рис. 6.8, г). Через некот мя память разделится на ряд областей, одни из которых будут содержать с а другие — неиспользованные области. Это называется внешней фрагм (поскольку неиспользованное пространство попадает не в сегменты, а в между ними, то есть процесс происходит вне сегментов). Иногда внешн ментацию называют поклеточной разбивкой.

Посмотрите, что произойдет, если программа обратится к сегмент момент, когда память подвергается внешней фрагментации (рис. 6.8, г пространство «дырок» составляет 10 Кбайт, а это больше, чем нужно для се но так как это пространство разбито на маленькие кусочки, сегмент 3 ту зить нельзя. Вместо этого приходится сначала удалять другой сегмент.

Чтобы избежать такой ситуации, нужно сделать следующее. Каждый р появляется «дырка», нужно перемещать сегменты, следующие за «дырко же к адресу 0, устраняя таким образом эту «дырку» и оставляя большую в конце. Есть и другой способ. Можно подождать, пока внешняя фрагм

Соседние файлы в предмете Аппаратное обеспечение ЭВМ, средств телекоммуникаций и сетей