Страницы

понедельник, 12 июля 2010 г.

Динамическая память (Dynamic Memory) приходит в Hyper-V Часть 3.

Итак ближайшее время займусь переводом публикации "Dynamic Memory Coming to Hyper-V Part 3...", так как данная публикация помимо массы интересной информации о страничном распределении памяти, обладает и значительным объемом, то переводить ее буду по частям, дополняя данный пост.

Ссылка на оригинал: Virtualization Team Blog.




Динамическая память (Dynamic Memory) приходит в Hyper-V Часть 3.

======================================================

Предисловие: Суть этой серии публикаций и дух в котором они написаны, должны показать комплексный подход к вопросам, стоящим перед нашими клиентами, обсуждение сложностей, связанных с управлением памятью, и объяснение почему для решения этих проблем мы выбрали динамическую память Hyper-V (Hyper-V Dynamic Memory). Это не обозначает критику кого-либо или каких-либо технологий, это проведение открытого и прозрачного обсуждения проблем.

======================================================

Memory Overcommit, термин перегрузки...

Когда речь заходит о виртуализации и памяти я часто слышу термин "memory overcommit", используемый так, как будто это единая технология. Проблема заключается в том, что есть множество технологий, которые могут быть задействованы для более эффективного использования памяти, но это может привести к еще большей путанице. Некоторые клиенты считают, что страничное распределение (page sharing) эквивалентно overcommit. Другие думают, что второй уровень подкачки эквивалентен memory overcommit и так далее.

Итак, чтобы избежать путаницы, вот определение overcommit из интернет-словаря Merriam Webster:
http://www.merriam-webster.com/dictionary/overcommit

overcommit - для чрезмерного выполнения
a: для совершения (действия) выходящего за пределы возможностей (собственных).
б: выделить (ресурсы) излишки мощностей для пополнения

Если сказать простыми словами memory overcommit означает следующее: выделить больше ресурсов памяти, чем физически присутствует. В физическом (не виртуальном) окружении, использование файла подкачки является примером memory overcommit. Теперь, когда мы определили это, я буду использовать этот термин, чтобы избежать вышеупомянутой путаницы. Также, с этого момента я буду ссылаться на конкретные технологии памяти.

В виртуальном окружении есть различные технологии работы с памятью, которые могут быть задействованы для более эффективного использования памяти, такие как страничное распределение, второй уровень подкачки и балансировка динамической памяти (напрмер одна из технологий: "balloning", горячее добавление/уменьшение памяти - другая). Каждый отдельно взятый метод имеет свои плюсы и минусы, а также различные уровни эффективности.

Сегодня мы детально обсудим страничное распределение (Page Sharing).

Кстати, прежде чем мы начнем погружение, позвольте мне сказать, что мы потратили много времени, разбирая эту технологию, и пришли к выводу, что это лучший вариант для использования с динамической памятью, Надеюсь у меня получится объяснить почему...



Как страничное распределение (Page Sharing) работает.

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

Страничное распределение это хорошее понимание технологии использования памяти и это набор факторов способствующих ее более эффективному использованию, таких как:
  1. Большие страницы памяти (Large Memory Pages)
  2. Использование памяти операционной системой (OS Memory Utilization) и Нулевые страницы (Zero Pages)


Страничное распределение, TLB, большие страницы памяти и так далее...

Для обсуждения поддержки больших станиц памяти и ее последствий для страничного распределения и ее влияния на страничное распределение, давайте сделаем шаг назад. Для этого, я буду ссылаться на отличную статью, которую сделал Alan Zeichick из AMD в 2006 году. Хотя статья сфокусирована на применении больших страниц памяти и виртуальных машинах java, это также применимо и к машинной виртуализации. Я буду ссылаться на конкретные разделы, но если вы пожелаете прочитать ее целиком, то она расположена вот по этой ссылке:
http://developer.amd.com/documentation/articles/pages/2142006111.aspx


Все процессоры с архитектурой x86 и современные 32-ух и 64-ех разрядные операционные системы размещают физическую и виртуальную память в страницах. Таблица страниц связывает виртуальный адрес с физическим для каждого приложения и поиск нужного значения в этой таблице занимает время. Чтобы ускорить этот процесс современные процессоры используют Translation Lookside Buffer (TLB), для кэширования наиболее частых связей между физической и виртуальной памятью.

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

Когда приложение нуждается в считывании или записи в память, процессор использует таблицу страниц для перевода (трансляции) адресов виртуальной памяти, используемых приложением, в адреса физической памяти. Как упоминалось ранее, для ускорения процессор использует систему кэширования - Translation Lookside Buffer (TLB). Если запрашиваемый адрес находится в кэше TLB, то процессор может обслужить запрос быстрее, без поиска адресов в таблице страниц. Если запрашиваемый адрес не находится в кэше, то процессор, перед ответом на запрос, переходит к таблице страниц для поиска соответствия виртуального адреса физическому.

TLB кэш имеет большое значение, так как страниц памяти очень много. В стандартных 32-разрядных Linux, Unix или Windows серверах с 4 ГБ оперативной памяти в таблице страниц присутствует миллион маленьких страниц по 4 КБ. Это очень много, но что если это 64-разрядная система с 32 ГБ оперативной памяти? Это означает, что в системе есть 8 миллионов страниц памяти по 4 КБ.

Мистер Zeichick продолжил:

Почему это [большие страницы] лучше? Предположим ваше приложение пытается прочитать 1 МБ (1024 КБ) непрерывных данных, к которым не было обращений последнее время и они не хранятся в кэше TLB. Если страница памяти имеет размер 4 КБ, это означает, что вам придется получить доступ к 256 отдельным страницам памяти. Это означает поиск не содержащихся в кэше 256 раз и затем поиск в таблице страниц 256 раз. Медленно, медленно, медленно.

В отличии от этого, если страница имеет размер 2 МБ (2048 КБ), тогда для доступа к блоку данных потребуется один или два запроса к таблице страниц - один если данные содержатся в одной странице и два если данные переходят через границу сраницы памяти. После этого TLB кэширует все необходимое. Быстрее, быстрее, быстрее.ли страница имеет размер 2 МБ (2048 КБ), тогда для доступа к блоку данных потребуется один или два запроса к таблице страниц - один если данные содержатся в одной странице и два если данные переходят через границу сраницы памяти. После этого TLB кэширует все необходимое. Быстрее, быстрее, быстрее.

Это становится лучше.

Для маленьких страниц, механизм TLB содержит 32 записи в L1 кэше и 512 записей в L2 кэше. Так как каждая запись ссылается на 4 КБ, вы можете посчитать что вместе они покрывают чуть более 2 МБ виртуальной памяти.

Для больших страниц TLB содержит восемь записей. Так как каждая страница отображает 2 МБ, TLB может показывать 16 МБ виртуальной памяти. Если ваше приложение обращается с большим объемом памяти, то в таком случае это намного эффективнее. Представьте себе выгоды если ваше приложение читает, ну скажем, 2 ГБ данных. Как считаете этот процесс для тысяч буферизованных страниц по 2 МБ, вместо полумиллиона страниц по 4 КБ?

Браво, мистер Zeichick.


Я расширил пример мистера Zeichick по сравнению физической памяти с количеством записей в таблице страниц и создал эту таблицу для дальнейших демонстраций страниц по 4 КБ на различных объемах физической памяти.

Физическая память - Записи таблицы страниц (4КБ)
4 ГБ - 1 миллион страниц
32 ГБ
- 8 миллионов страниц
64 ГБ
- 16 миллионов страниц
96 ГБ
- 24 миллиона страниц
128 ГБ
- 32 миллиона страниц
192 ГБ
- 48 миллионов страниц
256 ГБ
- 64 миллиона страниц
384 ГБ
- 96 миллионов страниц
512 ГБ
- 128 миллионов страниц
1 ТБ
- 256 миллионов страниц

Если учесть, что серверы не поддерживают 32/64 ГБ памяти вечно и что многие серверы сегодня, такие как HP DL 385 G6 поддерживают до 192 ГБ памяти на один сервер, вы увидите что время для использования больших страниц памяти давно настало. Взгляните на недавно выпущенный процессор Nehalem EX. Nehalem EX поддерживает до 256 ГБ памяти в каждый разъем. Теоретически вы можете владеть сервером с четырьмя разъемами и 1 ТБ физической памяти. Вы действительно хотите получать доступ к этой памяти по 4 КБ за раз?

(Уже используя 64 ГБ физической памяти работа с ней, как заполнение олимпийского бассейна при помощи маленьких емкостей: по 8 чашек за раз и чем больше памяти становится тем хуже...)

Ключевые моменты:

  • TLB является одним из важнейших ресурсов системы, который вы хотите использовать эффективно и настолько эффективно, насколько это возможно, так как это может оказать существенное влияние на производительность системы.
  • Использование 4 КБ-ых страниц в 32-битном мире, где системы максимально обладают 4 ГБ памяти была проблемой на протяжении нескольких лет, теперь проблема стала серьезней в 64-битном мире, где системы поддерживают десятки (если не сотни) гигабайт оперативной памяти.
  • Использование страниц памяти с размером 4 КБ на 64-битных с поддержкой огромных объемов памяти резко снижает эффективность TLB и общую производительность системы.

Еще больше: SLAT, NPT/RVI, EPT и большие страницы...

Один момент, который я хотел бы добавить, это то, как большие страницы и второй уровень трансляции адресов (Secound Level Address Translation, SLAT) сосуществуют на аппаратном уровне. Со встроенной подкачкой, (AMD называет это Rapid Virtualization Indexing (RVI ~ Быстрая индексация виртуализации) и/или Nested Page Tables (NPT ~ встроенные таблицы страниц), в то же время Intel называет это Extended Page Tables (EPT ~ расширенные таблицы страниц)) таблицы страниц на аппаратном уровне отвечают за трансляции между адресом гостевой виртуальной машиной и физическим адресом, сокращая затраты. С оборудованием, поддерживающим SLAT, производительность в целом увеличивается на 20% по всем направлениям, и может быть гораздо выше (независимая третья сторона сообщила о 100%+ приросте производительности), все зависит от того какая нагрузка приходится на память. Одним словом, аппаратная поддержка SLAT является правильным решением и если вы закупаете сервер в качестве виртуального хоста сегодня, необходимо удостоверится, что он обладает этой возможностью.

Один важный момент, который не так хорошо известен, это то что аппаратная технология SLAT, разработана и оптимизирована под использование больших страниц памяти. Нужно отметить, что дополнительные вложенные таблицы страниц, делают TLB кэш не выгодным и в результате теряется примерно 20% производительности, в том случае, когда вы используете возможности аппаратного SLAT с отключенными большими страницами памяти. Более того, здесь не учтены 10-20%-ное (может и больше) увеличение производительности, за счет использования больших страниц памяти. В общем мы говорим о 40%-ом приросте или потере производительности на оборудовании с поддержкой SLAT, в зависимости от того, используются ли большие страницы памяти или нет.

Вы можете захотеть прочитать эти последние два пункта еще раз.

Одним словом, большого ума не надо чтобы понять, что нужно использовать большие страницы памяти. Вы точно захотите воспользоваться возможностями больших страниц памяти:

  • Увеличение производительности (в среднем на 10-20%, может и больше).
  • Более эффективное использование TLB.
  • Избегайте 20% процентной потери производительности на оборудовании с поддержкой SLAT.


Эволюция оборудования, большие страницы памяти и последствия для страничного распределения (Page Sharing).

Компьютерное оборудование постоянно эволюционирует. Возьмите к примеру сетевые технологии. Ранее, размер кадра для Ethernet составлял 1518 байт, в значительной степени это связано с более низкой скоростью и большим количеством ошибок. Вместе с эволюцией и улучшением сетей (быстрые с малым количеством ошибок), размер в 1518 байт был признан узким местом, в связи с чем были введены большие кадры. Гигантские кадры (Jumbo frames) еще больше, они достигают 9014 байт и доставляют до 6 пакетов за раз, тем самым уменьшая нагрузку на процессор, за счет сокращения числа прерываний.

Аналогичная ситуация происходит в настоящее время с большими страницами памяти, где серверное оборудование развивается, увеличивая масштабы и производительность всей системы. Последствием такого развития становится изменение базовых допущений. В частности, большие страницы памяти изменяют фундаментальные допущения о маленьких страницах памяти по 4 Кб на большие и более эффективные страницы памяти по 2 Мб. Однако, есть и последствия таких изменений. Пока вы можете определять и распространять страницы по 4 КБ относительно легко, вероятность распространения страниц по 2 Мб очень, очень мала (если вообще не является нулевой). По сути в данной области Microsoft и VMWare солидарны. VMWare подтверждает эту точку зрения.

Из VMWare:
Единтсвенная проблема, связанная с использованием больших страниц, страничное распределение нуждается в поиске равных фрагментов для 2 Мб (по сравнению с 4 Кб фрагментами, когда используются маленькие страницы) и вероятность нахождения весьма мала (если гость записывает все нули в 2 Мб фрагмент) так ESX не пытается сокращать большие страницы и из-за этого память, сохраняемая за счет TPS уменьшается, в тот момент, когда все гостевые страницы передаются в большие страницы гипервизора.

http://communities.vmware.com/message/1262016#1262016

Страничное рапределение работает в наследстве от мира страниц памяти по 4 Кб, но не предоставляет ценности в современном мире страниц памяти по 2 Мб.

Как отмечалось ранее, поддержка больших страниц памяти не так уж и сложна. На самом деле, при проектировании Hyper-V Dynamic Memory, мы убедились в возможности оптимизации в случае использования больших страниц памяти, потому как мы ожидаем, что в скором времени они станут стандартом. Мы настолько уверены в поддержке больших страниц памяти, что:
  • В Windows Server 2008/2008 R2 большие страницы памяти разрешены по умолчанию.
  • В Windows Vista/7 большие страницы памяти разрешены по умолчанию.
  • В Windows Server 2008 R2 Hyper-V добавлена поддержка для больших страниц памяти (Сюрприз!) и это всего одно из улучшений производительности в R2.

Размер страницы памяти эволюционирует. Вы можете рассчитывать и на размер страниц памяти превышающий 2 Мб в будущем. На самом деле новые процессоры AMD64 могут использовать страницы памяти размером 1 Гб в длинном режиме, также и Intel добавляет поддержку страниц размером 1 GB в их выходящих процессорах Westmere. (Кстати, это не опечатка, страницы с размером 1 Гб...)

В дополнение к большим страницам памяти, другим фактором влияющим на эффективность страничного распределения является OS Memory Utilization(Использование памяти операционной системой) и Zero Pages (Нулевые страницы).


Страничное распределение (Page Sharing), использование памяти операционной системой (OS Memory Utilization) и нулевые страницы (Zero Pages).

Один из аспектов страничного распределения, о котором большинство людей могут не знать, заключается в том, что наибольшая выгода от страничного распределения получается за счет распределенного обнуления страниц. Давайте представим, что передо мной система Windows XP с 2 Гб памяти. Как вы можете видеть на снимке ниже, имеется только что загруженная система Windows XP, без приложений, операционная система использует ~375 МБ памяти, в то время как оставшиеся ~ 1,8 Гб памяти не задействованы и простаивает без пользы.


В действительно, вы хотите, чтобы операционная система полностью использовала всю память в качестве интеллектуального кэша для повышения производительности и гибкости. Если вы собираетесь купить новую систему (а я вижу в интернете рекламу новых четырех-ядерных систем с 8 Гб памяти за 499 долларов), разве вы не хотите чтобы операционная система использовала эту память? Конечно же вы хотите. Именно поэтому мы создали SuperFetch (Суперусиление).

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

Итак, как же на самом деле используется оперативная память? Вы наверняка заметили, что Windows 7 использует гораздо больше оперативной памяти, чем Windows XP. Это не редкость увидеть в диспетчера задач Windows 7, на системе с несколькими гигабайтами оперативной памяти, свободными менее 100 Мб. Для примера, вот диспетчер задач машины на которой я сейчас работаю:


Как вы можете увидеть, эта система обладает 8 Гб оперативной памяти и использует 3,29 Гб. Я запустил Windows 7 64-разрядную редакцию, Outlook, One Note, Word, Excel, PowerPoint, Windows Live Writer, Live Photo Gallery, несколько экземпляров IE c более чем дюжиной открытых вкладок и еще кучу других повседневных инструментов, и вы можете видеть, что доступно 0 Мб свободной физической памяти. На первый взгляд - это повод для беспокойства, но если помнить про SuperFetch, то становится ясно, что беспокоиться тут не о чем. Обратите внимание что ~5872 Мб используется для кеширования.

Превосходно.

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

Итак почему же я объясняю нулевые страницы и SuperFetch?

Потому что наибольшая выгода от страничного распределения достигалась за счет обнуления страниц в предыдущих версиях операционных систем, а в современных операционных системах это становится менее выгодным. Также как и Гигантские кадры и большие страницы памяти, SuperFeatch это новый пример эволюционных изменений в компьютерах.

В разговоре с клиентами, которые занимаются размещением виртуальных рабочих столов, нам сообщили, что Windows 7 является наиболее удачным выбором. Это еще один важный момент в понимании того, как мы выбрали динамическую память: потому что множество нулевых страниц для операционной системы сегодня не дает ничего хорошего и не даст в будущем.

Финальная точка в страничном распределении

Подведем итоги...

Сегодня доступна широкая поддержка больших страниц памяти (2 Мб) в процессорах AMD и Intel. AMD и Intel включили поддержку больших страниц памяти для многих поколений x86/x64 процессоров. Однако 32-разрядные системы не поддерживают большие объемы памяти (поддержка в большинстве случаев заканчивается на 4 Гб, которые составляют лишь малую часть от того объема, который поддерживается 64-разрядными системами), поэтому большие страницы памяти для них не столь важны, однако сейчас 64-разрядные серверы становятся нормой.

  • Страничное распределение на системах с большими страницами памяти в результате как правило не дают распределенных страниц. Пока вы можете относительно легко определить страницу размером 4 Кб, вероятность совместного использования страниц с размером 2 Мб очень, очень мала (если вообще не ноль). Опять же в этой области Microsoft и VMWare солидарны.
  • Прочитайте последний пункт еще раз.
  • Страничное распределение работает с маленькими страницами по 4 Кб. Недостатком маленьких страниц является неэффективное использование TLB, в случае использования больших страниц TLB используется более эффективно, что приводит к значительному увеличению производительности.
  • Использование маленьких страниц памяти по 4 Кб на оборудовании с поддержкой SLAT снижает производительность ~20%
  • В Windows Server 2008/2008 R2 большие страницы памяти включены по умолчанию.
  • В Windows Vista/7 большие страницы памяти включены по умолчанию.
  • В Windows Server 2008 R2 Hyper-V добавлена поддержка больших страниц памяти и это только одно из улучшений производительности в R2 (сюрприз!)
  • Эффективность страничного распределения снижается (это не связано с большими страницами памяти), так как современные операционные системы полностью используют оперативную память для увеличения производительности.
  • Процесс проверки, хэширования всей памяти в системе и записи в хэш таблицу может занимать часы. Время зависит от целого ряда переменных, таких как: однородность гостевых систем, какая нагрузка приходится на гостевые системы, сколько памяти на физической системе, используете ли вы балансировку нагрузки между виртуальными машинами и так далее.
  • Страничное распределение не является динамичной технологией, если гипервизор потребует памяти на другую виртуальную машину, то страничное распределение не является наилучшим ответом. Также верно и обратное. Если виртуальная машина освобождает память, которая может быть использована другими виртуальными машинами, то и в этом случае страничное распределение не является наилучшим ответом.

Я надеюсь данная публикация наглядно показывает, что мы потратили много времени рассматривая данную технологию и после тщательного анализа пришли к выводу, что это не лучший вариант для использования вместе с Hyper-V Dynamic Memory. Более того, много ума не нужно, чтобы понять необходимость поддержки больших страниц памяти. Мы настолько сильно уверены в больших страницах памяти, что при разработке Hyper-V Dynamic Memory, мы оптимизировали поддержку больших страниц памяти, так как мы ожидаем, что в скором времени она станет стандартом. Преимущества слишком очевидны, чтобы их упустить. Хорошая новость заключается в том, что существуют и другие способы объединения и выделения памяти, и Hyper-V Dynamic Memory является хорошим решением для настольных и серверных операционных систем.

В следующей публикации мы обсудим второй уровень подкачки.

Jeff Woolsey

Windows Server Hyper-V