УДК 004.451.3
П. В. Емельянов
Московский физико-технический институт ул. 9-я северная линия, д. 1, корп. 1, Москва, 127204, Россия
ОПТИМИЗАЦИЯ МОДЕЛИ КОНТРОЛЯ ПОТРЕБЛЕНИЯ ПАМЯТИ
ГРУППОЙ ПРОЦЕССОВ
В статье излагается подход к оптимизации работы алгоритма по подсчету количества физических страниц, использующихся группой процессов. Предлагаемый автором подход основан на модели управления памятью, принятой в операционных системах Unix. В рамках данной модели все физические страницы, которыми разрешено пользоваться процессам, выделяются в пределах предварительно созданных регионов. Идея оптимизации состоит в построении оценки количества этих физических страниц, зависящей от длин указанных регионов. В конце статьи приводятся результаты экспериментов с оптимизированным алгоритмом.
Ключевые слова: управление памятью, контроль ресурсов, оптимизация алгоритмов, виртуализация
Введение
Ядро любой операционной системы предоставляет пользователям компьютера различные ресурсы [Tanenbaum, Woodhull, 2006]. При этом наряду с задачей выделения ресурсов часто возникает задача их распределения - различные пользователи должны быть ограничены в потреблении того или иного ресурса, например, для защиты системы от умышленного потребления всех свободных ресурсов одним пользователем.
Современные операционные системы предоставляют пользователям и программам довольно большой набор ресурсов; например открытые файлы и сетевые соединения, объекты ядра операционной системы и сегменты памяти программ, сетевые буфера отправки и получения данных и многие другие. Однако в первом приближении ресурсов всего два - это процессорное время и объем памяти.
Данная работа посвящена контролю физической памяти, которая выделяется ядром для нужд исполняющихся программ. В качестве базовой выбрана операционная система Linux. В работе формулируется задача ограничения объема потребления памяти группами процессов, дается описание подсистемы управления памятью Linux, рассматриваются существующие модели, контролирующие потребление памяти группами процессов и выявляются их недостатки. Далее предлагается новый подход к проблеме, который основан на текущей модели управления памятью в Linux. В конце статьи приводятся результаты испытаний реализованной модели и рассматриваются пути ее дальнейшего развития.
Задача ограничения
Рассмотрим следующую задачу. Пусть имеется группа процессов, каждый из которых использует какой-то набор физических страниц 1 памяти [The Memory..., 2001]. При этом каждая страница, вообще говоря, может использоваться разными процессами. Все запросы на выделение очередной страницы памяти обрабатываются ядром операционной системы, причем ядро в праве отказать процессу в выделении очередной страницы (например, отправкой ему сигнала [Love, 2005]).
1 Страницей в теории управления памятью называется область памяти фиксированного размера (например, 4096 байт), которая является минимальной единицей выделяемой памяти.
ISSN 1818-7900. Вестник НГУ. Серия: Информационные технологии. 2008. Том 6, выпуск 1 © П. В. Емельянов, 2008
Требуется организовать работу системы таким образом, чтобы группе процессов не позволять использовать более определенного количества страниц, но при этом не принимать во внимание то, как распределены страницы между процессами внутри этой группы. Такая задача часто возникает в многопользовательских операционных системах для обеспечения изоляции пользователей друг от друга. В более общем виде задача ставится в современных системах виртуализации, где под группой понимается не отдельный пользователь, а виртуальная среда или машина, которая должна быть изолирована от остальных [OpenVZ..., 2006; Linux..., 2007; The Xen., 2007]. Решение данной задачи, очевидно, зависит от того, как происходит управление памятью в самой операционной системе. Поэтому, прежде всего, рассмотрим, как это происходит в ОС Linux.
Модель управления памятью в Linux
Ключевым понятием в теории управления памятью ОС является понятие виртуальной памяти [The Memory, 2001]. Виртуальная память - это схема адресации компьютерной памяти, при которой она представляется выполняющимся на компьютере программам непрерывной и однородной, в то время как для физического хранения данных используются несвязанные области различных физических носителей, таких как линейки оперативной памяти или жесткие диски. Остановимся подробнее на модели выделения памяти процессам, которая реализована в ядре Linux [Love, 2005]. Выделение памяти в Linux осуществляется последовательно в два этапа.
Первый этап - создание региона отображения - заключается в том, что процессу в его виртуальном адресном пространстве [The Memory., 2001] выделяется диапазон адресов, при обращении к которым разрешается выделять физические страницы памяти. При этом физической памяти процессу не выделяется. Эти диапазоны называются «регионами отображения» и, помимо начала и конца, характеризуются еще рядом параметров, такими как права доступа или наличие отображенного в регион файла [Ibid.].
Запрос на создание очередного региона осуществляется с помощью специального системного вызова - mmap (рис. 1). Заметим, что размер региона всегда слегка изменяется ядром так, чтобы он был кратен размеру страницы.
Второй этап - выделение физических страниц - состоит в выделении физической страницы и отображении ее в виртуальное адресное пространство процесса. Данный этап, в отличие от предыдущего, происходит незаметно для процесса.
При создании региона отображения ядро ОС с помощью «страничных таблиц» 2 настраивает отображение [Ibid.] виртуальных адресов в физические. Делается это таким образом, чтобы при первом обращении к памяти по этому виртуальному адресу происходило аппаратное исключение, называемое «страничным отказом», и управление передавалось в ядро.
Процесс просто обращается к участку виртуального адресного пространства, например, записывая какое-нибудь значение по определенному адресу. Затем ядро, получив описанным образом управление, может выделить физическую страницу и, перенастроив отображение, вернуть управление процессу (рис. 2). Дальнейшее обращение к памяти по этому адресу уже не вызовет никакого аппаратного исключения, и программа продолжит работу. Важно заметить, что при обращении процесса по адресу, находящемуся вне созданных регионов, ядро не выделяет физическую память, а отправляет процессу специальный сигнал [Love, 2005].
Выгрузка страниц на диск. Как было описано ранее, программа может выполняться, не имея в наличии части физических страниц, а получая их лишь по запросу. Эта возможность используется в ситуации, когда в системе заканчиваются физические страницы оперативной памяти. В этом случае ядро операционной системы копирует часть страниц из оперативной памяти на жесткий диск или другой более вместительный носитель. Страничные таблицы при этом настраиваются ядром так, чтобы обращение к этим страницам опять приводило к страничному отказу.
2 Набор таблиц, с помощью которых процессор ставит соответствие между физическими адресами памяти и виртуальными.
Существующие наработки
Единственным и очевидным решением задачи ограничения является перехват всех запросов на выделение страниц и ведение счетчиков, показывающих, сколько страниц какими группами используется.
Проект CKRM. Одна из реализаций такого подхода была предложена в проекте CKRM [CKRM..., 2006]. В этой модели алгоритм подсчитывает количество страничных отказов и количество выгруженных на диск страниц. Разница этих величин считается количеством выделенных физических страниц. Недостаток данного подхода очевиден - он не учитывает того факта, что одна и та же страница может быть использована несколькими процессами в группе. Такая ситуация возможна, когда два процесса из одной группы отображают один и тот же файл в свое виртуальное адресное пространство и начинают читать из него данные. В этом случае ядром будет выделена лишь одна физическая страница, несмотря на то, что на нее будут ссылаться два разных региона.
Рис. 1. Создание «региона отображения»
Рис. 2. Выделение физической памяти
В этом случае возможна следующая ситуация. Если счетчик показывает, что группа использует N страниц, то это может означать практически что угодно - как то, что в системе действительно выделено N страниц и каждая из них используется каким-либо процессом, так и то, что в системе выделена всего одна страница и она используется N различными процессами. Так же, конечно, возможен и любой из промежуточных вариантов.
Система контроля ресурсов Beancounters. Другой подход к проблеме описан в работе «Resource management: Beancounters» [Emelianov et al., 2007]. Суть подхода состоит в том, что с каждой физической страницей ассоциируется массив так называемых «счетчиков использования». Каждый такой счетчик показывает, сколько процессов из соответствующей группы используют данную страницу. Вся работа со счетчиками ведется в коде, отвечающим за обработку страничных отказов. Однако, в отличие от предыдущего подхода, считается, что количество выделенных физических страниц для группы равно количеству соответствующих ей ненулевых счетчиков.
Таким образом, если одна страница будет использоваться N процессами в группе, то соответствующий странице и группе счетчик будет иметь значение N . При этом количество используемых страниц будет равно 1. Тем не менее данный подход обладает одним существенным недостатком. Дело в том, что код ядра Linux, отвечающий за обработку страничных отказов, является так называемым «быстрым путем» [Wadleigh, Crawford, 2000] и существует в ядре с момента его создания. По этой причине данный код уже очень хорошо оптимизирован, и существенные внедрения в него ведут к заметным потерям производительности ядра. Например, введение тат называемого «атомарного» (т. е. рассчитанного на одновременное использование в параллельно выполняющихся процессах) счетчика, о котором говорилось выше, дает падение производительности на 10 %, что является весьма плохим показателем.
Алгоритм 1. Изменения в обработке страничных отказов:
Вход: i - регион, в котором выделяется страница
1. if запрашиваемая страница находится в регионе i then
2. ^ шаг 9
3. end if
4. if ^ Ri = R then
5. послать процессу сигнал
6. return
7. end if
8. R ^ R +1
9. выделить страницу и настроить отображение
10. return
В данном же подходе алгоритм работы со счетчиком является довольно емким по времени (алгоритм 1). При каждом страничном отказе производится проверка, не принадлежит ли запрашиваемая физическая страница группе, и изменяется значение атомарного счетчика. Как показывают измерения, все это вкупе приводит к почти 20 %-й потере производительности (см. рис. 5).
Тем не менее данная модель предоставляет хорошую основу для дальнейших разработок -в рамках этой модели были решены все проблемы, оставшиеся нерешенными в проекте CKRM, хотя и за счет заметной потери в производительности. В следующем разделе будет описано, как можно сохранить производительность не модифицированного ядра, сохранив все возможности, предоставляемые подсистемой beancounters.
Обзор предлагаемого метода решения
Суть подхода состоит в следующем. Не вмешиваясь в каждый страничный отказ, замедляя работу системы, предлагается вместо количества используемых физических страниц
взять некую оценку, которая являлась бы средним значением между реальным количеством физических страниц и суммарным размером регионом отображения.
Количество физических страниц, используемых процессами, всегда ограничено размерами описанных регионов. А поскольку размеры этих регионов всегда не меньше, чем количество используемых страниц, ограничивая это значение (и улучшая оценку при необходимости), можно добиться требуемой цели - ограничения группы в использовании физической памяти - не замедляя при этом работу кода, обрабатывающего страничные отказы.
Это возможно благодаря тому, что, в отличие от кода, обрабатывающего страничные отказы, код системного вызова mmap не является «быстрым путем». Так что даже существенные внедрения в него не влекут сколько-нибудь заметных потерь производительности.
Теоретически количество используемых физических страниц в отдельном регионе может равняться его размеру. Практически же их число почти всегда гораздо меньше [Love, 2005] размера региона. По этой причине нельзя просто ограничивать длины регионов для группы -такой метод, как правило, будет вести к тому, что процессы окажутся не в состоянии использовать память вообще, либо к тому, что администратор будет вынужден задавать слишком большие пределы. Таким образом, оценку количества используемых страниц требуется улучшать по мере того, как регионы становятся больше.
Математическая модель
Введем следующие обозначения:
• m - количество регионов отображения в данной группе;
• R - количество страниц, используемых в i -м регионе;
• - размер i -го региона в страницах. Измерение размера региона в страницах возможно благодаря тому, что ядро всегда подгоняет границы региона соответствующим образом;
• Et - рассчитываемая оценка величины Ri;
• 5; - признак, используется ли в i -м отображении в качестве оценки точное значение R или верхняя оценка Mt. Данная величина принимает значение 1 в первом случае и 0 во втором. Для простоты изложения в дальнейшем к регионам с 5г- = 1 будет применяться термин «медленные», а для регионов с 5г- = 0 - «быстрые»;
• R - предел потребления физических страниц для данной группы. Данная величина задается, как правило, администратором системы.
Итак, требуется организовать работу кода, отвечающего за обработку страничных отказов, и системного вызова mmap так, чтобы всегда выполнялось следующее соотношение:
Учтем, что в силу особенностей модели управления памятью в Linux количество используемых физических страниц всегда не больше, чем длины регионов отображения, т. е.
В соответствии с предлагаемой моделью для каждого региона будем рассчитывать оценку Ei , равную
m
Z R < R.
(1)
i =0
Ri < M...
(2)
E = SR +(1 - SM-).
Из (2) и (3) нетрудно видеть, что
R= SR+(1 - SR)< 8Д+(1 - SIM<) = E,
m
m
и, следовательно,
Таким образом, решая задачу
m
E = £ E, < R,
i = 0
мы автоматически решаем и задачу (1). При этом величина
m
p = Е 5i
i = 0
будет характеризовать производительность системы. Чем меньше р, тем меньше регионов отображения требуют рассчитанного значения Ri и, следовательно, тем быстрее работает система.
Алгоритм работы
Прямое решение по ограничению использования физических страниц, как было показано в алгоритме 1, приводит лишь к изменениям в коде обработки страничных отказов. Важно отметить, что шаги 1-8 в описанном алгоритме являются довольно трудоемкими, что и приводит к существенным потерям в производительности (см. рис. 5).
Наиболее тяжелым является шаг 1, в котором производится проверка того, используется ли запрашиваемая физическая страница текущей группой или нет, чтобы избежать проблем, возникших в проекте CKRM.
Алгоритм 2. Изменения в системном вызове mmap:
Вход: size - размер региона
1. while E + size > R do
2. find i - регион, такой, что 5i = 0
3. if i не существует then
4. ^ шаг 15
5. end if
6. 8i ^ 1
7. Ri ^ подсчитанное значение Ri
8. Ei ^ Ei - + R
9. end while
10. E ^ E + size
11. создать новый регион i
12. Mt ^ size
13. 5г ^ 0
14. return
15. создать новый регион i
16. R ^ size
17. 5г ^ 1
18. return
Алгоритм работы системы в соответствии с описанной моделью потребует изменений в коде системного вызова mmap и в коде обработки страничных отказов (алгоритмы 2 и 3).
Алгоритм 3. Оптимизация в обработке страничных отказов:
Вход: i - регион, в котором выделяется страница
1. if 5г- = 0 then
2. ^ шаг 12
3. end if
4.
5.
6.
7.
8.
9.
10.
if запрашиваемая страница находится в регионе i then ^ шаг 12
end if
if E = R then
послать процессу сигнал return
10. end if
11. e ^ e +1
12. выделить страницу и настроить отображение
13. return
Но в отличие от старого алгоритма в новом алгоритме для быстрых регионов медленный код обходится. Поскольку проверка этого значения для региона занимает лишь несколько инструкций процессора, которые не требуют синхронизации с другими процессорами, такой код не привносит заметных потерь в производительности, что показано на рис. 5.
О корректности работы алгоритма
Утверждение. Невозможна ситуация, в которой ОС отказывает процессу в выделении физической страницы, когда оценка не является точной, то есть часть регионов имеют значение 5; равное 0 .
Доказательство. Прежде всего заметим, что имеет место следующее соотношение:
Доказательство проведем от противного. Допустим, что существует регион, у которого значение 5; равно 0 , и во время обработки страничного отказа в регионе с 5г-, равным 1, имеет
место E +1 > R • Это значит, что суммарная длина регионов больше, чем R в силу (4). Это аналогично тому, что при создании очередного региона суммарная их длина превысила R, но алгоритм в таком случае переводит все регионы в значение 5г-, равное 1, что противоречит предположению.
Результаты тестирования
Изложенный выше подход реализован автором в рамках проекта по контролю памяти [Emelianov et al., 2007], который является частью более крупного проекта по виртуализации сервисов операционной системы [OpenVZ..., 2006].
Для проверки применимости изложенного подхода был проведен ряд экспериментов, для которых был взят стандартный набор тестов под названием unixbench [UnixBench, 2007]. Этот набор включает в себя ряд небольших программ, проверяющих скорость выполнения основных действий с ресурсами ОС. Например, скорости открытия файла, передачи данных по каналу, выделения памяти и т. д. Но основной интерес, конечно, представляли тесты, связанные с выделением памяти. Испытания проводились на двухпроцессорной машине, чтобы оценить влияние атомарных счетчиков на работу алгоритма.
Тесты запускались последовательно в специально созданной группе. Всего было произведено 15 испытаний, для каждого из которых на группе предел потребления памяти ( R ) увеличивался на 8 Mb. Представленные графики демонстрируют, как меняются различные параметры системы в зависимости от установленных пределов.
На рис. 3 представлена информация о том, как менялись суммарные длина регионов M = I Mt , уровень потребления физической памяти R = IR и вычисленная оценка
m
m
(4)
Как видно, величина R действительно оказалась существенно меньше M (в данном случае почти в 5 раз). Также видно, что с ростом предела R оценка E ухудшается и приближается к M .
На рис. 4 показано, как менялось количество медленных регионов, для которых осуществлялся точный подсчет Et . Видно, что с ростом предела действительно появляется возможность использовать верхние оценки для большего количества регионов, что и дает предлагаемой модели выигрыш в производительности по сравнению с системой beancounters.
И, наконец, рис. 5 демонстрирует влияние алгоритма на производительность системы. Как видно, умеренные увеличения предела R дают заметный выигрыш в производительности за счет того, что в системе присутствует большее количество быстрых регионов, что позволяет большему количеству страничных отказов обходить стороной медленный код, не ухудшая производительности системы. Таким образом, предлагаемая оптимизация системы beancounters приблизила суммарную производительность ядра с механизмом контроля потребляемой памяти к производительности не модифицированного ядра.
48 64 00 96
R, Mb
Рис. 3. Соотношения M, R и E
Дальнейшее направление исследований
Выбор «быстрого» региона. В алгоритме 2 не уточняется, как именно выбирается быстрый регион. Однако от выбора такого региона зависит производительность всей группы. Например, если сначала выбирать регионы, в которых страничные отказы происходят не часто, можно позволить регионам с частыми страничными отказами работать быстро.
На рис. 3 видно, что оценка E всегда находится предельно близко к пределу R (к прямой y = x), что говорит о том, что регион всегда выбирался оптимальным образом. Причину этого легко понять - в группе, взятой для эксперимента, все процессы всегда выполнялись и использовали память. Для групп, в которых присутствуют мало использующие память процессы, результаты могут оказаться хуже.
Переключение в «быстрый» режим. Как видно из приведенных алгоритмов, модель может постепенно переключить все регионы в медленный режим. Однако если с течением времени окажется, что величина R (а вместе с ней и E) опять уменьшилась, то можно часть регионов снова перевести в быстрый режим работы. При этом следует учитывать тот факт, что на каждое переключение требуется время для подсчета R., и слишком частые переключения могут свести на нет всю оптимизацию.
Заключение
В статье рассматривается задача ограничения групп процессов в потреблении физической памяти, которая часто возникает в многопользовательских операционных системах и особенно остро стоит в современных системах виртуализации [OpenVZ..., 2006; Linux..., 2007; The Xen..., 2007]. Автором описаны несколько подходов к решению данной задачи [CKRM..., 2006, Emelianov et al., 2007] и выявлены их недостатки. Среди описанных подходов выделена наиболее полно проработанная модель управления памятью - модель beancounters - и предложена ее модернизация, нацеленная на улучшение производительности системы.
Приведена математическая модель улучшения, и представлены в упрощенном виде алгоритмы для ее реализации. Данная модель была также реализована автором в рамках крупного проекта по виртуализации сервисов операционной системы на базе ОС Linux.
Несмотря на то что подход существенно опирается на модель управления памятью в самой операционной системе, он может быть применен в различных ОС, которые организуют управле-
Рис. 5. Производительность ядер
ние памятью в соответствии с описанной моделью. Такая модель является развитием модели, описанной в стандарте POSIX, и используется в ряде других операционных систем.
В конце статьи приводятся результаты измерений производительности, которые показывают жизнеспособность модели, и приводятся дальнейшие направления для исследований.
Список литературы
CKRM linux open source project. Class based kernel resource management [Электронный ресурс] / IBM [2006]. Режим доступа: http://ckrm.sourceforge.net/, свободный. Загл. с экрана. Яз. англ.
Emelianov P., Lunev D., Korotaev K. Resource Management: Beancounters: Proc. of the 2007 Ottawa Linux Symposium. 2007. P. 285-292.
Linux Vserver [Электронный ресурс] / Open Source Project [2007]. Режим доступа: http://linux-vserver.org, свободный. Загл. с экрана. Яз. англ.
Love R. Linux Kernel Development. Novell Press, 2005. Chapter 14: The Process Address Space.
OpenVZ Virtualization and Isolation [Электронный ресурс] / Open Source Project [2006]. Режим доступа: http://openvz.org/, свободный. Загл. с экрана. Яз. англ.
Tanenbaum A. S. , Woodhull A. S. Operating Systems: Design and Implementation: 2nd ed. Prentice Hall, 1997.
The Memory Management Reference [Электронный ресурс] / Ravenbrook [2001]. Режим доступа: http://www.memorymanagement.org/, свободный. Загл. с экрана. Яз. англ.
The Xen Virtual Machine Monitor [Электронный ресурс] / Open Source Project [2007]. Режим доступа: http://www.cl.cam.ac.uk/research/srg/netos/xen/, свободный. Загл. с экрана. Яз. англ.
UnixBench [Электронный ресурс] / Suite for POSIX System Benchmarking [2007]. - Режим доступа: http://sourceforge.net/projects/unixbench/, свободный. Загл. с экрана. Яз. англ.
Wadleigh K. R., Crawford I. L. Software Optimization for High Performance Compiting: Creating Faster Applications. Prentice Hall PTR, 2000. Chapter 7.4: Suboutine of Function Call Overhead.
Материал поступил в редколлегию 22.03.2008
P. V. Emelianov
An Optimization for the Algorithm of Group Memory Consumption Control
Given in this article is an approach to optimization of the algorithm, that accounts for the number of physical pages allocated for a group of processes. This approach is based on the memory management model, that is used in a Unix operating systems. This model implies that all the physical pages, used by tasks can be allocated within a pre-created regions only. The optimization idea is to calculate an estimation to the number of allocated pages, that depends on the total length of those regions. At the end of the article there are the results of experiments with an optimized algorithm.
Keywords: memory management, resource control, algorithm optimization, virtualization.