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

spz / spz

.pdf
Скачиваний:
33
Добавлен:
23.02.2016
Размер:
5.16 Mб
Скачать

8

цей список і виділяє задачі розділ у тій області, що перша підійде по обсягу.

У цьому випадку, якщо такий фрагмент є, то в середньому необхідно переглянути половину списку. При звільненні роздягнулу також необхідно переглянути половину списку. Правило «перший підходящий» приводить до того, що пам'ять для невеликих задач переважно буде виділятися в області молодших молодших адрес і, отже, це буде збільшувати імовірність того, що в області старших адрес будуть утворюватися фрагменти досить великого обсягу.

Спосіб «самий придатний» припускає, що список вільних областей впорядкований по зростанню обсягу цих фрагментів. У цьому випадку при перегляді списку для нового розділу буде використаний фрагмент вільної пам'яті, об’єм якої найбільш точно відповідає необхідному. Необхідний розділ буде визначатися як і раніше в результаті перегляду в середньому половини списку.

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

Як не дивно, найефективнішим правилом є останнє, по якому для нового розділу виділяється «самий невідповідний» фрагмент вільної пам'яті. Для цієї дисципліни список вільних областей впорядковується по убуванню обсягу вільного фрагмента. Очевидно, що якщо є такий фрагмент пам'яті, то він відразу ж до буде знайдений, і оскільки цей фрагмент є найбільшим, то, швидше за все, після виділення з нього розділу пам'яті для задачі область, що залишилася, ще зможе бути використана в подальшому.

Через те, що задачі з'являються і завершуються в довільні моменти часу і при цьому вони мають різні обсяги, то в пам'яті завжди буде спостерігатися сильна фрагментація. Можливі ситуацій, коли через сильну фрагментацію пам'яті диспетчер задач не зможе утворити новий розділ, хоча сумарний обсяг вільних областей буде більше, ніж необхідно для задачі. У цій ситуації організується - ущільнення пам'яті. Для ущільнення пам'яті всі обчислення припиняються, і диспетчер пам'яті коректує свої списки, переміщаючи розділи. Недоліком цього рішення є втрата часу на ущільнення і неможливість при цьому виконувати обчислювальні процеси.

Даний спосіб розподілу пам'яті проте застосовувався досить довгий час у операційних системах, оскільки в ньому для задач виділяється неперервний адресний простір, а це спрощує створення систем програмування і їхню роботу.

1

Сегментна, сторінкова і сегментно-сторінкова організація пам'яті.

1.Сегментний спосіб організації віртуальної пам'яті.

2.Дисципліни заміщення: FIFO; LRU (1еаst recently used,); LFU (1еаst frequently used); random.

3.Сторінковий спосіб організації віртуальної пам'яті.

4.Сегментно-сторінковий спосіб організації віртуальної пам'яті.

Сегментна, сторінкова і сегментно-сторінкова організація пам'яті

Методи розподілу пам'яті, при яких задачі вже може не надаватися суцільна область пам'яті, називають розривними. Ідея виділяти пам'ять задачі не однією суцільною областю, а фрагментами вимагає для своєї реалізації відповідної апаратної підтримки — потрібно мати відносну адресацію. Якщо вказувати адреса початку поточного фрагмента програми і величину зсуву щодо цієї початкової адреси, то можна вказати необхідну нам перемінну чи команду. Таким чином, віртуальну адресу можна представити, як таку, що складається з двох полів. Перше поле буде вказувати частину програми (з якою зараз здійснюється робота) для визначення місця розташування цієї частини в пам'яті, а друге поле віртуальної адреси дозволить знайти потрібну нам комірку відносно щодо знайденої адреси. Програміст може або самостійно розбивати програму на фрагменти, або автоматизувати цю задачу і покласти її на систему програмування.

Сегментний спосіб організації віртуальної пам'яті

Першим серед розривних методів розподілу пам'яті був сегментний. Для цього методу програму необхідно розбивати на частині і вже кожнії такій частині виділяти фізичну пам'ять. Природним способом розбивки програми на частині є розбивка її на логічні елементи — так називані сегменты. У принципі кожен програмний модуль (чи їхня сукупність, якщо ми того побажаємо) може бути сприйнятий як окремий сегмент, і вся

програма тоді буде являти собою безліч сегментів. Кожен сегмент розміщається в пам'яті як самостійна одиниця.

Логічно звертання до елементів програми в цьому випадку буде представлятися як вказівка імені сегмента і зсуву відносно початку цього сегменту. Фізично ім'я (або порядковий номер) сегменту буде відповідати деякій адресі, з якого цей сегмент починається при його розміщенні в пам’яті, і зсув повинний додаватися до цієї базової адреси.

2

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

Відповідна ілюстрація приведена на мал. На цьому малюнку зображений випадок звертання до комірки, віртуальна адреса якої дорівнює сегменту з номером 11 і зміщенням від початку цього сегмента, рівним 612. Як Ми бачимо, операційна система розмістила даний сегмент у пам'яті, починаючи з комірки з номером 19 700.

Кожен сегмент, розташований у пам'яті, має відповідну інформаційну структуру, часто називану дескриптором сегмента. Саме операційна система будує для кожного процесу, що виконується, відповідну таблицю дескрипторів сегментів і при розміщенні кожного з сегментів в оперативній чи зовнішній пам'яті в дескрипторі відзначає його поточне місцезнаходження. Якщо сегмент задачі в даний момент знаходится в оперативній пам'яті, то про це робиться позначка в дескрипторе. Як правило, для цього використовується “біт присутності“ (present). У цьому випадку в поле «адреса» диспетчер пам'яті записує адресу фізичної пам'яті, з якого сегмент починається, а в поле «довжина сегмента» (limit) указується кількість адресуємих комірок пам'яті. Це поле використовується не тільки для того, щоби розміщати сегменти без накладання один на “інший” але і для того, щоб проконтролювати, чи не звертається код задачі, що виповнюється, за межі поточного сегмента. В випадку перевищення довжини сегмента унаслідок помилок програмування ми можемо говорити про порушення адресації і за допомогою введення спеціальних апаратних засобів генерувати сигнали переривання» які дозволять фіксувати (виявляти) такого роду помилки.

Отже, якщо необхідного сегмента в оперативній пам'яті немає, то виникає переривання і керування передається через диспетчер пам'яті програмі завантаження сегмента. Поки відбувається пошук сегмента в зовнішній пам'яті і завантаження його в оперативну, диспетчер пам'яті визначає придатне для сегмента місце.

Можливо, що вільного місця немає, і тоді приймається рішення про вивантаження якого-небудь сегмента і його переміщення в зовнішню пам'ять. Якщо при цьому ще залишається час, то процесор передається іншій готовій до виконання задачі. Після завантаження необхідного сегмента процесор знову передається задачі, що викликала переривання через відсутність сегмента. Усякий раз при зчитуванні сегмента в оперативну пам'ять у таблиці

3

дескрипторів сегментів необхідно установити адресу початку сегмента й ознаку присутності сегмента.

При пошуку вільного місця використовується одна з перерахованих вище дисциплін роботи диспетчера пам'яті (застосовуються правила «першого придатного» і «самого невідповідного» фрагментів). Якщо вільного фрагмента пам'яті достатнього обсягу зараз немає, але сума вільних фрагментів перевищує вимоги по пам'яті для нового сегмента, то в принципі може бути застосоване «ущільнення пам'яті», про яке ми говорили.

В ідеальному випадку розмір сегмента повинний бути досить малим, щоб його можна було розмістити у випадково вивільнюваних фрагментах оперативної пам'яті, але досить великим, щоб містити логічно закінчену частину програми для того, щоб мінімізувати міжсегментні звертання.

Для рішення проблеми заміщення (визначення того сегмента, який повинний бути або переміщений у зовнішню пам'ять, або просто заміщений новим) використовуються наступні дисципліни (їх наз. дисципліни заміщення):

правило FIFO (first in first out, що означає: «перший прийшов першим і вибуває»);

правило LRU (1еаst recently used, що означає «останній з недавно використаних» чи, інакше кажучи, «довше всього невикористовуваний»);

правило LFU (1еаst frequently used, що означає: «використовуваний рідше всіх інших»);

випадковий (random) вибір сегмента.

Перша й остання дисципліни є найпростішими в реалізації, але вони не враховують, наскільки часто використовується той чи інший сегмент і, отже, диспетчер пам'яті може чи вивантажити розформувати той сегмент, до якого в самому найближчому майбутньому буде звертання. Безумовно, достовірної інформації про те, який із сегментів буде потрібно в найближчому майбутньому, у загальному випадку мати не можна, але імовірність помилки для цих дисциплін вище, ніж у другої і третьої дисципліни, що враховують інформацію про використання сегментів.

Алгоритм FIFO асоціює з кожним сегментом час, коли він був поміщений у пам'ять. Для заміщення вибирається найбільш старий сегмент. Облік часу необов'язковий, коли всі сегменти в пам'яті зв'язані в FIFO-чергу і кожен сегмент, що поміщається в пам'ять, додається в хвіст цієї черги. Алгоритм враховує тільки час перебування сегмента в пам'яті, але не враховує фактичне використання сегментів. Наприклад, перші завантажені сегменти програми можуть містити перемінні, використовувані протягом

4

роботи всієї програми. Це приводить до негайного повернення до тільки що заміщеного сегмента.

Для реалізації дисциплін LRU і LFU необхідно, щоб процесор мав додаткові апаратні засоби. Мінімальні вимоги — досить, щоб при звертанні до дескриптора сегмента для одержання фізичної адреси, з якого сегмент починає розташовуватися в пам'яті, відповідний біт звертання змінював своє значення (скажемо, з нульового, яке встановила ОС, в одиничне). Тоді диспетчер пам'яті може час від часу переглядати таблиці дескрипторів задач, що виповнюються, і збирати для відповідної обробки статистичну інформацію про звертання до сегментів. У результаті можна скласти список, упорядкований або по тривалості не використання (для дисципліни LRU), або по частоті використання (для дисципліни LFU).

Найважливішою проблемою, що виникає при організації мультипрограмного режиму, є захист пам'яті. Для того щоб додатки, що виконуються, не змогли зіпсувати саму ОС і інші обчислювальні процеси, необхідно, щоб доступ до таблиць сегментів з метою їхньої модифікації був забезпечений тільки для коду самої ОС. Для цього код ОС повинний виконуватися в деякому привілейованому режимі, з якого можна здійснювати маніпуляції з дескрипторами сегментів, тоді як вихід за межі сегмента в звичайній прикладній програмі повинний викликати переривання по захисту пам'яті. Кожна прикладна задача повинна мати можливість звертатися тільки до своїх власних сегментів.

При використанні сегментного способу організації віртуальної пам'яті з'являється кілька цікавих можливостей. По-перше, з'являється можливість при завантаженні програми на виконання розміщати її в пам'яті не цілком, а «у міру необхідності». Дійсно, оскільки в переважній більшості випадків алгоритм, по якому працює код програми, є розгалуженим, а не лінійним, то в залежності від вихідних даних деякі частини програми, розташовані в самостійних сегментах, можуть бути і не задіяні; виходить, їх можна і не завантажувати в оперативну пам'ять.

По-друге, деякі програмні модулі можуть бути поділюваними. Ці програмні модулі є сегментами, і в цьому випадку відносно легко організувати доступ до таких сегментів. Сегмент із поділюваним кодом розташовується в пам'яті в єдиному екземплярі, а в декількох таблицях дескрипторів сегментів задач, що виконуються, будуть знаходитися покажчики на такі поділювані сегменти.

Однак у сегментного способу розподілу пам'яті є і недоліки. Для одержання доступу до шуканої комірки пам'яті необхідно витратити набагато більше часу. Ми повинні спочатку знайти і прочитати дескриптор сегмента, а

5

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

Для того щоб зменшити ці втрати, використовуються кешування — тобто ті дескриптори, з якими ми маємо справу в даний момент, можуть бути розміщені у сверхоперативній пам'яті (спеціальних регістрах, розташовуваних у процесорі).

Незважаючи на те, що цей спосіб розподілу пам'яті приводить до істотно меншої фрагментації пам'яті, ніж способи з нерозривним розподілом, фрагментація залишається. Крім цього, ми маємо великі втрати пам'яті і процесорного часу на розміщення й обробку дескрипторних таблиць. Адже на кожну задачу необхідно мати свою таблицю дескрипторів сегментів. А при визначенні фізичних адрес необхідно виконувати операції додавання .

Тому наступним способом розривного розміщення задач у пам'яті став спосіб, при якому усі фрагменти задачі однакового розміру і довжини, кратного ступеня двійки, щоб операції додавання можна було замінити операціями конкатенації (злиття). Це — сторінковий спосіб організації віртуальної пам'яті. |

Прикладом використання сегментного способу організації віртуальної пам'яті є операційна система для ПК OS/2 першого покоління (1984-1987рр.), що була створена для процесора і80286.

Сторінковий спосіб організації віртуальної пам'яті

При такому способі усі фрагменти програми, на які вона розбивається (за винятком останньої її частини), виходять однаковими. Однаковими рахуються й одиниці пам'яті, що ми надаємо для розміщення фрагментів програми. Ці однакові частини називають сторінками і говорять, що пам'ять розбивається на фізичні сторінки, а програма — на віртуальні сторінки. Частина віртуальних сторінок задачі розміщається в оперативній пам'яті, а частина — у зовнішній. Звичайно місце в зовнішній пам'яті, у якості якої в більшості випадків виступають нагромаджувачі на магнітних дисках (оскільки вони відносяться до швидкодіючих пристроїв із прямим доступом), називають файлом підкачки або сторінковим файлом. Іноді цей файл називають swap-файлом, тим самим підкреслюючи, що записи цього файлу

— сторінки — заміщають один одного в оперативній пам'яті. У Unixсистемах для цих цілей виділяється спеціальний розділ, але крім нього можуть бути використані і файли, що виконують ті ж функції, якщо обсягу розділу недостатньо.

6

Розбивка всієї оперативної пам'яті на сторінки однакової величини, причому величина кожної сторінки вибирається кратною ступеню двійки, приводить до того, що замість одномірного адресного простору пам'яті можна говорити про двовимірний. Перша координата адресного простору — це номер сторінки, а друга координата — номер комірки всередині обраної сторінки (його називають індексом). Таким чином, фізична адреса визначається парою (Рр, і), а віртуальна адреса — парою (Рv, і), де Рv — це номер віртуальної сторінки, Рр — це номер фізичної сторінки, і це індекс комірки у середині сторінки. Кількість бітів, що відводиться під індекс, визначає розмір сторінки, а кількість бітів, що відводиться під номер віртуальної сторінки, — обсяг можливої віртуальної пам'яті, яким може користуватися програма. Відображення, здійснюване системою під час виконання, зводиться до відображення Рv в Рр і приписуванні до отриманого значення бітів адреси, що задаються величиною і. При цьому немає необхідності обмежувати число віртуальних сторінок числом фізичних, тобто сторінки, що не помістилися, можна розміщати в зовнішній пам'яті, і це у даному випадку служить розширенням оперативної.

Для відображення віртуального адресного простору задачі на фізичну пам'ять, як і у випадку із сегментним способом організації, для кожної задачі необхідно мати таблицю сторінок для трансляції адресних просторів. Для опису кожної сторінки диспетчер пам'яті ОС заводить відповідний дескриптор, що відрізняється від дескриптора сегмента насамперед тим, що в ньому немає необхідності мати поле довжини — адже всі сторінки мають однаковий розмір. По номері віртуальної сторінки в таблиці дескрипторів сторінок поточної задачі знаходиться відповідний елемент (дескриптор). Якщо біт присутності має одиничне значення, виходить, дана сторінка зараз розміщена в оперативній, а не в зовнішній пам'яті і ми в дескрипторі маємо номер фізичної сторінки, відведеної під дану віртуальну. Якщо ж біт присутності дорівнює нулю, то в дескрипторі ми будемо мати адресу віртуальної сторінки, розташованої зараз у зовнішній пам'яті. У такий спосіб і здійснюється трансляція віртуального адресного простору на фізичну пам'ять.

Захист сторінкової пам'яті, як і у випадку із сегментним механізмом, заснований на контролі рівня доступу до кожної сторінки. Як правило, можливі наступні рівні доступу: тільки читання; читання і запис; тільки виконання. У цьому випадку кожна сторінка забезпечується відповідним кодом рівня доступу.

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

7

При звертанні до віртуальної сторінки, якої не має в даний момент у оперативної пам'яті, виникає переривання і керування передається диспетчеру пам'яті, що повинний знайти вільне місце. Звичайно надається перша ж вільна сторінка. Якщо вільної фізичної сторінки немає, то диспетчер пам'яті по одній з вищезгаданих дисциплін заміщення (LRU, LFU, FIFO, random) визначить сторінку, що підлягає розформуванню або збереженню в зовнішній пам'яті. На її місце він розмістить ту нову віртуальну сторінку, до якої було звертання з задачі, але її не виявилося в оперативній пам'яті.

Алгоритм вибирає для заміщення ту сторінку, на яку не було посилання протягом найбільш довгого періоду часу. Для заміщення вибирається та сторінка, що довше усіх не використовувалася.

Якщо обсяг фізичної пам'яті невеликий і навіть часто використовуємі сторінки не вдається розмістити в оперативній пам'яті, то виникає так звана «пробуксовка». Іншими словами, пробуксовка — це ситуація, при якій завантаження потрібної нам сторінки викликає переміщення в зовнішню пам'ять тієї сторінки, з яким ми теж активно працюємо. Очевидно, що це дуже погане явище. Щоб його не допускати, бажано збільшити обсяг оперативної пам'яті (зараз це стало самим простим рішенням), зменшити кількість рівнобіжно виконуваних задач або спробувати використовувати більш ефективні дисципліни заміщення.

В абсолютній більшості сучасних ОС використовується дисципліна заміщення сторінок LRU, як сама ефективна. Вона використовується в OS/2 i Linux. Але в Windows NT, розробники, бажаючи зробити систему максимально незалежною від апаратних можливостей процесора використали правило FIFO. А для того , щоб згладити її неефективність, була введена “буферизация”.

Її принцип простий. Перш ніж заміщувана сторінка буде переміщена в зовнішню пам’ять, вона помічається як кандидат на вивантаження. Якщо в наступний раз буде звернення до сторінки, яка знаходиться в такому буфері, то сторінка не вивантажується, а стає в кінець черги FIFO. В іншому випадку сторінка дійсно вивантажується і на її місце в буфер попадає наступний кандидат. Об’єм такого буфера не може бути великим і тому ефективність сторінкової організації пам’яті набагато нижче чим у вищезгаданих систем, і явище пробуксовки починається навіть при дуже великому об’ємі оперативної пам’яті. (В системі Windows NT файл з вивантаженими віртуальними сторінками носить назву PageFile.sys. Таких файлів може бути декілька. Їх загальний об’єм має бути не менший ніж об’єм фізичної пам’яті плюс 11Мб, які необхідні самій Windows NT. В системах Windows 2000 розмір цього файлу набагато перевищує об’єм фізичної пам’яті і буває досягає сотень мегабайт).

8

Таким чином, найважливішим достоїнством сторінкового способу організації пам’яті є мінімальна фрагментація. Оскільки на кожну задачу може приходитися по одній незаповненій сторінці, то очевидно, що пам’ять використовується ефективно. Цей метод можна було назвати найкращим, якщо б не наступних дві обставини.

Перше – сторінкова трансляція віртуальної пам’яті вимагає суттєвих накладних витрат. Таблиці сторінок необхідно розміщати теж в пам’яті. Крім цього ці таблиці необхідно обробляти – з ними працює диспетчер пам’яті.

Другий недолік – програми розбиваються на сторінки випадково, без обліку логічних зв’язків. Це приводить до того, що міжсторінкові переходи відбуваються частіше ніж міжсегментні і стає важко організовувати поділ програмних модулів між процесами, що виконуються.

Для того щоб уникнути другого недоліку, зберігши достоїнства сторінкового способу організації пам’яті, було запропоновано ще один спосіб

– сегментно-сторінковий. Правда, за рахунок подальшого збільшення вимагає суттєвих накладних витрат.

Сегментно-сторінковий спосіб організації віртуальної пам'яті

Як і в сегментному способі розподілу пам'яті, програма розбивається на логічно закінчені частини — сегменти — і віртуальна адреса містить указівку на номер відповідного сегмента. Друга складова віртуальної адреси — зсув відносно початку сегмента — у свою чергу, може складатися з двох полів: віртуальної сторінки й індексу. Іншими словами, виходить, що віртуальна адреса тепер складається з трьох компонентів: сегмент, сторінка, індекс.

Цей спосіб організації віртуальної пам'яті вносить ще більшу затримку доступу до пам'яті. Необхідно спочатку обчислити адресу дескриптору сегмента і прочитати його, потім обчислити адресу елементу таблиці сторінок цього сегменту і витягти з пам'яті необхідний елемент, і вже тільки після цього можна до номера фізичної сторінки приписати номер комірки в сторінці (індекс). Затримка доступу до шуканої комірки виходить принаймні в три рази більше, ніж при простій прямій адресації.

Щоб уникнути цієї неприємності, вводиться кешування, причому кэш, як правило, будується по асоціативному принципі.

( Іншими словами, перегляди двох таблиць у пам'яті можуть бути замінені одним звертанням до асоціативної пам'яті.

9

Нагадаємо, що принцип дії асоціативного запам'ятовуючого пристрою припускає, що кожній комірці пам'яті такого пристрою ставиться у відповідність комірка, у якій записується деякий ключ (ознака, адреса), що дозволяє однозначно ідентифікувати вміст комірки пам'яті. Супутню комірку з інформацією, що дозволяє ідентифікувати основні дані, звичайно називають полем тега. Перегляд полів тега всіх осередків асоціативного пристрою пам'яті здійснюється одночасно, тобто в кожній комірці тега є необхідна логіка, що дозволяє за допомогою побітової кон’юнкції знайти дані по їх ознаці за одне звертання до пам'яті (якщо вони там присутні). Часто поле тегів називають аргументом, а поле з даними — функцією. Як аргумент при доступі до асоціативної пам'яті виступають номер сегменту і номер віртуальної сторінки, а як функцію від цих аргументів одержуємо номер фізичної сторінки. Залишається приписати номер комірки в сторінці до отриманого номера, і ми одержуємо шукану команду чи операнд.)

Оцінимо достоїнства сегментно-сторінкового способу.

Розбивка програми на сегменти дозволяє розміщати сегменти в пам'яті цілком.

Сегменти розбиті на сторінки, усі сторінки сегмента завантажуються в пам'ять. Це дозволяє зменшити звертання до відсутніх сторінок, оскільки імовірність виходу за межі сегмента менше імовірності виходу за межі сторінки.

Сторінки сегмента, що виконується, знаходяться в пам'яті, але при цьому вони можуть знаходитися не поруч один з одним, а «розсипом», оскільки диспетчер пам'яті маніпулює сторінками.

Наявність сегментів полегшує реалізацію поділу програмних модулів між рівнобіжними процесами.

Можливе і динамічне компонування задачі. А виділення пам'яті сторінками дозволяє мінімізувати фрагментацію.

Однак, оскільки цей спосіб розподілу пам'яті вимагає дуже значних витрат обчислювальних ресурсів то його не так просто реалізувати, використовується він рідко, причому в дорогих, могутніх обчислювальних системах. Можливість реалізувати сегментно-странковий розподіл пам'яті закладений і в сімейство мікропроцесорів і80х86, однак унаслідок слабкої апаратної підтримки, труднощів при створенні систем програмування й операційної системи, практично він не використовується в ПК.

Соседние файлы в папке spz