| Управління пам'яттю в MACOS і Win16
У цих системах передбачається, що призначені для користувача програми не зберігають
покажчиків на динамічно виділені блоки пам'яті. Замість цього кожен
такий блок ідентифікується цілочисельним дескриптором або "ручкою"
(handle) (мал. 4.16). Коли програма безпосередньо звертається до даних
в блоці, вона виконує системний виклик GiobaiLock
(замкнути). Цей виклик повертає поточну адресу блоку. Поки програма
не виконає виклик GiobaiUniock (відімкнути)система не
намагається змінити адресу блоку. Якщо ж блок не замкнутий, система рахує себе
має право пересувати його по пам'яті або навіть скидати на диск (мал.
4.17).
"Ручки" є спробою створити програмний аналог
апаратних диспетчерів пам'яті. Вони дозволяють вирішити проблему фрагментації
і навіть організувати деяку подібність віртуальної пам'яті. Можна розглядати
їх як засіб організації оверлейних даних — почергового відображення
різних блоків даних на одні і ті ж адреси. Проте за це доводиться
платити дуже дорогою ціною.
Використання "ручок" сильно ускладнює програмування взагалі
і особливо перенесення ПО з систем, що використовують лінійний адресний простір.
Всі покажчики на динамічні структури даних в програмі потрібно замінити
на "ручки", а кожне звернення до таких структур необхідно
оточити викликами GlobalLock/GlobalUnlock.
Мал. 4.16. Управління пам'яттю за допомогою "ручок"
Виклики GlobalLock/GlobalUnlock:
- самі по собі збільшують об'єм коди
і час виконання;
- заважають компіляторам виконувати
оптимізацію, перш за все не дозволяють оптимально використовувати
регістри процесора, тому що далеко не всі регістри зберігаються при
викликах;
- вимагають розриву конвеєра команд і перезавантаження командного
кеша; у сучасних суперскалярних процесорах це може наводити до
падіння продуктивності у багато разів.
Спроби зменшити число блокувань вимагають певних
інтелектуальних зусиль. Фактично, до звичайного циклу розробки ПО: проектування,
вибір алгоритму, написання коди і його відладка — додаються ще 16 фаз:
мікрооптимізація використання "ручок" і відладка оптимізованої коди.
Остання фаза виявляється, мабуть, найскладнішою і відповідальнішою.
Мал. 4.17. Дефрагментація при управлінні пам'яттю за допомогою
"ручок"
Найбільш небезпечною помилкою, що виникає на фазі мікрооптимізації, є
винесення покажчика на динамічну структуру за межі дужок GiobaiLock/ciobaiUniock
. Цю помилку дуже складно виявити при тестуванні, оскільки вона виявляється,
лише якщо система намагалася пересувати блоки в проміжках між зверненнями.
Іншими словами, помилка може проявляти або не проявляти себе залежно від
набору додатків, що виконуються в системі, і від характеру діяльності
цих застосувань. В результаті ми отримуємо те, чого більш всього бояться
эксплуатационщики — систему, яка працює інколи. При переході від Windows
3.x до Windows 95 напрацювання на відмову — навіть при виконання тієї ж самої
суміші додатків — різко зросла, так що система з тієї, що працює
інколи перетворилася на ту, що працює як
правило. Мабуть, це означає, що велика частина помилок в
додатках Winl6 дійсно відносилася до помилок роботи з "ручками".
Не випадково фірма Microsoft повністю відмовилася від управління пам'яттю
з помошью "ручок" в наступній версії MS Windows — Windows 95,
в якій реалізована майже повноцінна виртуатьная пам'ять.
Мас
OS версії 10, побудована на ядрі BSD Unix, також має сторінкову віртуальну
пам'ять і ніколи не перемішає блоки пам'яті, що адресуються "ручками". |