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

Учебное пособие 800330

.pdf
Скачиваний:
3
Добавлен:
01.05.2022
Размер:
1.64 Mб
Скачать

непосредственно из PDE таблицы каталога страниц. Смещение при этом 21-битное.

Чтобы отличать PDE, адресующие 2-мегабайтные страницы, от PDE, адресующих таблицы страниц, как и

ранее, используется флаг PS. Если

, то PDE адресует

большую страницу, а если

 

 

таблицу страниц.

= 0

– то = 1

Кроме того, если

,

меняется трактовка

некоторых битов в PDE, как

показано на рис. 34.

= 1

 

 

 

32

 

 

 

 

11

8

3

 

 

 

 

Адрес страницы

0

AVL

G

D A

P

0

(Биты 31...21)

AVL2

 

 

Адрес страницы

 

32

 

 

(Биты 51...32)

 

11

 

 

 

20

 

 

Рис. 34. Формат PDE в 64-битном режиме

 

 

для 2-мегобайтных страниц

 

 

Назначение всех полей и флагов уже было описано

ранее.

101

5. ВИРТУАЛЬНАЯ ПАМЯТЬ В LINUX

Рассмотрим в качестве примера реальной реализации виртуальную память в операционной системе Linux. Linux – это широко распространенная и динамично развивающаяся современная операционная система с открытым исходным кодом. Доступность исходных кодов позволяет детально изучить реализацию всех системных механизмов, в том числе системы виртуальной памяти. Приведем основные структуры, используемые в системе виртуальной памяти Linux. Будем придерживаться версии ядра 3.17.

5.1. Описание адресного пространства процессов

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

Рассмотрим основные поля структуры mm_struct.

struct mm_struct {

//список сегментов памяти struct vm_area_struct * mmap;

//альтернативное представление сегментов памяти

//в виде бинарного дерева для быстрого поиска rb_root_t mm_rb;

102

// указатель на каталог страниц ВАП pgd_t * pgd;

// число сегментов памяти int map_count;

// число резидентных страниц unsigned long total_vm

// начальный и конечный адреса сегмента кода unsigned long start_code, end_code;

// начальный адрес сегмента стека start_stack;

};

Таким образом, описание ВАП содержит, прежде всего, перечень сегментов, определенных в ВАП. Каждый сегмент описывается структурой vm_area_struct. Рассмотрим ее основные поля.

struct vm_area_struct {

//начальный адрес сегмента в ВАП unsigned long vm_start;

//адрес первого байта за сегментом unsigned long vm_end

//указатели для построения линейного списка сегментов struct vm_area_struct *vm_next, *vm_prev;

//узел бинарного дерева

//для альтернативного представления сегментов

struct rb_node vm_rb;

//указатели на функции, которые вызываются

//при страничной ошибке, отображении страницы и т.п. const struct vm_operations_struct *vm_ops;

// ссылка на отображенный файл (или NULL) struct file * vm_file;

};

103

5.2. Описание физической памяти

При разработке современных аппаратных платформ (архитектур) компьютеров значительное внимание уделяется оптимизации доступа к памяти. Реализация некоторых механизмов оптимизации доступа к памяти на многопроцессорных платформах приводит к тому, что различные участки памяти (различные диапазоны адресов в общем адресном пространстве) обеспечивают различную скорость работы (иногда говорят различную стоимость обращения) при обращении к ним со стороны разных процессоров. Такая концепция построения многопроцессорной аппаратной платформы обычно называется архитектурой с неравномерным доступом к памяти (в технической литературе часто используется аббревиатура NUMA Non-Uniform Memory Access).

Для оптимизации работы с памятью на платформах NUMA, в системе Linux вся доступная физическая память разделятся на блоки (их называют узлы – node) в соответствии с распределением адресов памяти в NUMA.

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

104

Например, на платформе x86-64 используется четыре зоны памяти: ZONE_DMA, ZONE_DMA32, ZONE_NORMAL и ZONE_HIGHMEM.

Узел памяти занимает некоторый непрерывный диапазон адресов физического адресного пространства, но в некоторых архитектурах в этом диапазоне могут быть пропуски (дыры, holes) – диапазоны адресов, которые не могут быть использованы для размещения данных, например. Эти диапазоны адресов зарезервированы архитектурой для собственных нужд, например для BIOS.

Узел памяти описывается структурой pglist_data, для которой определен псевдоним pg_data_t. Рассмотрим основные поля этой структуры.

typedef struct pglist_data {

//здесь хранятся все зоны памяти данного узла;

//массив резервируется под все возможные типы зон;

//в версии ядра 3.17 может быть до 5 типов зон,

//в зависимости от аппаратной платформы,

//при этом обязательно представлена ZONE_NORMAL struct zone node_zones[MAX_NR_ZONES];

// число зон памяти в узле (от 1 до MAX_NR_ZONES) int nr_zones;

//число доступных страничных кадров в узле unsigned long node_present_pages;

//«размер» узла в страничных кадрах,

//включая пропуски (holes), если они есть unsigned long node_spanned_pages;

//Указатель на процесс замещения страниц

//kernel swap daemon

struct task_struct *kswapd

} pg_data_t;

105

Зоны памяти описываются структурой zone. Перечислим некоторые поля этой структуры.

struct zone {

// пороговые величины свободной памяти unsigned long watermark[NR_WMARK];

//обратный указатель на структуру узла,

//содержащего данную зону

struct pglist_data *zone_pgdat;

// номер первого страничного кадра зоны unsigned long zone_start_pfn;

//общее число страничных кадров зоны, включая дыры unsigned long spanned_pages;

//фактическое число доступных страничных кадров зоны unsigned long present_pages;

// текстовое имя зоны const char *name;

//hash-таблица очередей процессов,

//заблокированных в ожидании загрузки страницы wait_queue_head_t *wait_table;

//число элементов в hash-таблице

//очередей заблокированных процессов

unsigned long wait_table_hash_nr_entries;

//массив заголовков списков свободных блоков

//для выделения памяти по методу близнецов struct free_area free_area[MAX_ORDER /* 11 */];

};

Структура free_area, описывающая список свободных блоков одинакового размера, определена следующим образом:

struct free_area {

struct list_head free_list[MIGRATE_TYPES];

106

unsigned long nr_free; // число элементов в списке

};

Видно, что на самом деле для каждого размера блока поддерживается несколько списков, по которым свободные блоки распределяются в зависимости от того, как ранее использовался блок и какое его использование предпочтительно в дальнейшем. Если в списке окажутся два смежных свободных блока, называемые близнецами, то они объединяются в один более крупный блок, который переносятся в список свободных блоков соответствующего размера и т.д. рекурсивно. Размер блока при использовании метода близнецов часто называют порядок блока – order, имея в виду, что размер блока равен 2 . Алгоритм близнецов, используемый Linux, предложен Кеном Ноултоном [9] и усовершенствован Дональдом Кнутом [10].

При этом элементы списка free_list связываются через поле lru структуры page, которая описывает состояние страничного кадра и его текущее использование.

В ядре Linux на этапе инициализации ядра создается массив структур page, так что каждая физическая страница (каждый страничный кадр) имеет ассоциированную с ним структуру page. При этом номер страничного кадра соответствует индексу структуры page в этом массиве.

107

ЗАКЛЮЧЕНИЕ

Несмотря на разнообразие современных операционных систем (Linux, Windows, FreeBSD, Solaris, OS X и множество других), все они используют очень близкую концепцию управления памятью.

Управление памятью всех современных операционных систем основано на концепции виртуальной памяти, предложенной 1956 г. немецким физиком ФрицемРудольфом Гюнтшем из Берлинского технического университета в его докторской диссертации «Логическое проектирование цифровой вычислительной машины с несколькими асинхронными вращающимися барабанами и автоматическим высокоскоростным управлением памятью».

Наиболее сложной проблемой при реализации виртуальной памяти стала задача эффективного замещения данных. Теоретические основе для ее решения были заложены в конце 60-х гг. XX века в работах Белади [1] и Деннинга [2, 3, 4]. Их труды до настоящего времени не потеряли своей актуальности, а предложенные идеи практически без изменений используются в новейших операционных системах.

Оптимизация управления памятью в современных операционных системах продвигается, прежде всего, в направлении повышения быстродействия, в том числе за счет использования большего объема памяти. Стоимость памяти существенно сократилась за последние десятилетия, а объем адресуемой памяти возрос миллионы раз. Широко используется кэширование, SLAB, SLOB и SLUB распределители памяти (все основаны на том, что после освобождения блока памяти программой, использовавшей его для размещения некоторых структур данных, освободившиеся блоки не возвращаются в «кучу», а сохраняются в списках (кэшах), чтобы при новых запросах

108

программ на размещение в памяти тех же типов структур данных (весьма вероятных ввиду локализации ссылок), использовать эти сохраненные блоки вместо выделения новых). Значительный объем памяти в современных компьютерах позволяет широко использовать SLAB/SLOB/SLUB распределители без риска возникновения дефицита памяти.

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

Общие сведения об управлении памятью в операционных системах можно получить из учебников [5, 6], а также из специальной литературы, описывающей конкретные операционные системы, например, [7, 8]. Также весьма полезно изучение открытых исходных кодов операционных систем Linux, FreeBSD, OpenSolaris.

БИБЛИОГРАФИЧЕСКИЙ СПИСОК

1.Belady, L. A. A study of replacement algorithms for a virtual-storage computer [Text] / L. A. Belady. – IBM Syst. J. – 1966. – 5(2). – P. 78–101.

2.Denning, P. J. The working set model for program behavior [Text] / P. J. Denning. – ACM Commun. – 1968.

11 (May). – P. 323-333.

109

3.Denning, P. J. Thrashing: Its causes and prevention [Text] / P. J. Denning. – Proc. AFIPS Fall Joint Comput. Conf. – 1968. – 32. – P. 915-922.

4.Denning, P. J. Resource allocation in multiprocess computer systems [Text] / P. J. Denning, Ph.D. Thesis. – Massachusetts Institute of Technology. – Dept. of Electrical Engineering. – 1968.

5.Дейтел, Г. Введение в операционные системы [Текст]: пер. с англ. / Г. Дейтел. – М.: Мир, 1987.

6.Таненбаум, Э. Современные операционные системы [Текст]: 3-е изд.; пер. с англ. / Э. Таненбаум. –

СПб.: Питер, 2010. – 1120 с.

7.Gorman, M. Understanding the Linux Virtual Memory Manager [Text] / M. Gorman. – Prentice Hall PTR, 2004. – 768 p. – ISBN 0-13-145348-3.

8.Руссинович, М. Внутреннее устройство

Microsoft Windows: Windows Server 2003, Windows XP

иWindows 2000 [Текст]: пер. с англ. / М. Руссинович, Д. Соломон. – СПб.: Питер, 2005. – 992 с.

9.Knowlton, K. C. A fast storage allocator [Text] / K. C. Knowlton. – ACM Commun. – 1965., 8 (October). – P. 623–624.

10.Knuth, D. E. The Art of Computer Programming, Vol. 1: Fundamental Algorithms [Text] / D. E. Knuth. – Addison-Wesley, Reading, Mass., 1968. – 634 p. – ISBN 0- 201-03801-3

110