Linux Kernel (Ядро линукса) (часть 2)


Базисное дерево

В Linux файлы могут быть очень большими, до нескольких терабайт. При работе с большим файлом кэш страниц может оказаться заполненным таким большим количеством страниц файлов, что последовательное их сканирование может потребовать слишком много времени. Для повышения эффективности просмотра кэша страниц в Linux 2.6 используется большой набор деревьев поиска, по одному на каждый объект address space.

Поле page tree объекта address space является корнем базисного дерева, содержащего указатели на дескрипторы страниц владельца. При заданном индексе страницы, обозначающем ее позицию в образе диска ее владельца, ядро может выполнить довольно быстрый просмотр и определить, находится ли в кэше требуемая страница. При поиске страницы ядро интерпретирует индекс как путь по базисному дереву и быстро доходит до места, где хранится (или должен храниться) дескриптор страницы. Найдя дескриптор, ядро может прочитать его, а также быстро определить, является ли страница "грязной” (нужно ли ее принудительно записать на диск), и происходит ли в этот момент ввод/вывод данных страницы.

Каждый узел базисного дерева может иметь до 64 указателей на другие узлы или на дескрипторы страниц. Узлы нижнего уровня содержат указатели на дескрипторы страниц (листья), а узлы на более высоких уровнях содержат указатели на другие узлы (потомки). Каждый узел представлен структурой radix tree node, состоящей из трех полей: slots, массива из 64 указателей, count, счетчика указателей, не равных null, и tags (двухэлементного массива флагов, который мы обсудим в разд. "Теги базисного дерева" далее в этой главе). Корень дерева представлен структурой radix tree root, которая имеет три поля, height обозначает текущую высоту дерева (количество уровней, исключая уровень листьев), gfpmask задает флаги, используемые при запросе памяти для нового узла, a mode указывает на структуру radix tree node, соответствующую узлу на уровне 1 (если таковой имеется).

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

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

В базисном дереве предпринят аналогичный подход. Эквивалентом линейного адреса здесь является индекс страницы. Однако количество полей, рассматриваемых в индексе страницы, зависит от высоты базисного дерева. Если она равна 1, представлены только индексы от 0 до 63, и шесть младших битов индекса страницы интерпретируются как индекс в массиве slots для единственного узла на уровне 1. Если же базисное дерево имеет высоту 2, то индексы представляют диапазон от 0 до 4095. Тогда 12 младших битов индекса страницы разбиваются на два поля по 6 битов. Старшее поле служит индексом массива для узла на уровне 1, а младшее — индексом массива для узла на уровне 2. Для любой другой высоты базисного дерева предпринимается аналогичный подход. При высоте, равной 6, два старших бита индекса страницы содержат индекс массива для узла первого уровня, следующие 6 битов содержат индекс массива для узла на уровне 2, и т. д. до шести младших битов, содержащих индекс массива для узла на уровне 6.
Если максимальный индекс в базисном дереве меньше индекса страницы, которую нужно добавить, ядро соответственно увеличивает высоту дерева. Содержимое промежуточных узлов базисного дерева зависит от значения индекса страницы.

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без про...

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга...

Linux Kernel (Ядро линукса) (ч...

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

Linux Kernel (Ядро линукса) (ч...

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно...

Linux Kernel (Ядро линукса) (ч...

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer...