понедельник, 26 декабря 2011 г.

ESX CPU scheduler deepdive. Multicore-Aware Load Balancing. Part 1.

Архитектура CMP (chip mutiprocessor) привносит новые проблемы алгоритмам балансировки нагрузки ввиду различных вариантов исполнения кэша на чипе. Предыдущие поколения процессоров обычно были с частным L2 кэшем, а более новые имеют общий как L3, так и L2 кэш. Также, количество ядер, использующих общий кэш варьируется от двух до четырех и более. Кэш последнего уровня (LLC - last level cache) - кэш, после которого идет обращение к оперативной памяти. Поскольку задержка при доступе к LLC и RAM различается как минимум на порядок, поддержание высокого уровня cache-hit для LLC становится жизненно необходимым для высокой производительности.
Балансировка нагрузки достигается миграцией vCPU, но после миграции vCPU должен "разогреть" кэш. И в связи с этим реальная стоимость миграции очень сильно зависит от того, требует ли разогрев кэша доступа к оперативной памяти, который не может быть удовлетворен за счет LLC. Иными словами, миграция в пределах LLC значительно дешевле, чем между LLC. Ранее эта внутричиповая топология игнорировалась планировщиком и стоимость миграции считалась одинаковой и фиксированной. Тем не менее, результат был удовлетворительным, поскольку механизм приоритезации миграции между ячейками планировщика (scheduler cell) приводил к высокому уровню между-LLC миграций - ячейка в большинстве случаев равняется одному, как максимум двум LLC.
В ESX4 понятие ячейки планировщика более не используется, а следовательно между-LLC миграции более не приоритезируются. Таким образом механизм балансировки нагрузки занчительно улучшился, поскольку миграция внутри LLC предпочтительнее миграции между LLC. Когда планировщик выбирает pCPU для миграции, локальный процессор, разделяющий LLC, всегда предпочтительнее удаленного, не разделяющего тот же LLC. Тем не менее, миграция на удаленный pCPU все еще возможна, если выбор локального pCPU не может решить проблему балансировки нагрузки.

CPU Load-Based Migration Throttling

В ESX4 vCPU, привносящий значительную нагрузку на текущий pCPU не будет мигрировать, вместо этого планировщик будет в первую очередь мигрировать vCPU с низкой нагрузкой. Данный механизм позволяет снизить количество миграций из-за мнимого дисбаланса. В низконагруженных средах легко может оказаться, что лишь несколько процессоров заняты, поскольку не хватает vCPU, способных нагрузить систему. Попытка выровнять нагрузку в данном случае приведет к ненужным миграциям и снизит производительность.
Например, один vCPU дает 95% нагрузки на pCPU (PA), в то время как остальные pCPU простаивают. Если другой простаивающий pCPU (PB) инициирует миграцию vCPU, то через некоторое время оригинальный pCPU (PA) станет проистаивающим и инициирует миграцию назад. Таким образом приоритезация миграции по нагрузке избавляет нас от этого пинг-понга. Высокая нагрузка на pCPU также означает и высокий вклад в кэш, поскольку у vCPU достаточно времени для разогрева кэша и соотв. высокой доли использования кэша. Это, конечно, не идеальная следственная связь, но вполне разумное предположение. Приоритезация миграций в зависимости от нагрузки на процессор может рассматриваться как необходимое условие для приоритезации миграций на основе рабочего набора в кэше. Точное определение размера рабочего набора в кэше и использование этого для приоритезации миграций - то, что возможно, будет реализовано в следующих версиях гипервизора.
Миграция vCPU начинает приоритезироваться по нагрузке только при условии, что vCPU имеет действительно большую долю в нагрузке на текущий pCPU. Пороговое значение установлено достаточно большим, чтобы разрешать миграции, действительно улучшающие общую производительность. По мере роста нагрузки на систему в целом приоритезация становится все менее вероятной ввиду того, что вклад каждого vCPU в процентном соотношении снижается. Проблема мнимого дисбаланса актуальна только для недозагруженных систем.

Impact on Processor Caching

В ESX4 vCPU виртуальной машины может быть размещен на любом pCPU, поскольку ячейки планировщика ушли в небытие. При работе алгоритма балансировки на основе нагрузки на LLC есть тенденция к разбеганию vCPU одной виртуальной машины по разным LLC. Тем не менее, все они остаются в пределах одного узла NUMA, если машина управляется планировщиком NUMA. Большее количество агрегированного кэша и ширины канала доступа к памяти улучшают производительность для большинства видов нагрузок. Однако нагрузки с интенсивной межпроцессной комуникацией могут страдать от снижения производительности при размещении по разным LLC.
Например, рассмотрим параллельное приложение с малым рабочим набором кэша, но очень частым взаимодействием производитель-потребитель взаимодействием между нитями. Также предполжим, что эти нити распределены по различным vCPU. Если хост недозагружен, то скорее всего vCPU были распределены между различными LLC. Таким образом взаимодействие между нитями приводит к большому количеству cache-miss и общему снижению производительности. Если бы рабочий набор был больше, чем LLC, то политика по-умолчанию улучшила бы производительность.
Относительный эффект большего агрегированного кэша в значительной степени зависит от приложения. Также как и с предыдущим механизмом, динамическое определение типа приложения и изменение политики планировщика на лету бросает новые выовы и будет составлять основу будущей работы. На сегодняшний день можно вручную принудительно задать политику консолидирования кэша.

vSMP Consolidation

Если есть уверенность, что приложение в виртуальной машине получит выигрыш от разделяемого кэша, а не от большего его объема, этот эффект можно достичь при консолидации vSMP. Консолидация vSMP приведет к приоритезации выбора pCPU в пределах  LLC для vCPU данной ВМ. Тем не менее, иногда это может и не случиться, в зависимости от доступности pCPU.
Для включения консолидации vSMP необходимо изменить следующий расширенный параметр для ВМ: 
sched.cpu.vsmpConsolidate = true.

Продолжение следует.

Оригинал: "VMware® vSphere™: The CPU Scheduler in VMware ESX® 4.1"

2 комментария:

  1. Меня давно мучает вопрос - а возможно ли консолидировать несколько vCPU одной многопроцессорной ВМ на одном pCPU? Как думаешь?

    ОтветитьУдалить
  2. Технически возможно, но бессмысленно. За счет попыток выравнивать исполнение по разным vCPU будет ОЧЕНЬ большая просадка производительности.

    Не исключено, что ты не сможешь стартовать машину с большим количеством vCPU, чем есть физических ядер - будет ругаться гипервизор. Сейчас просто не на чем проверить.
    В любом случае больше производительности, чем при #vCPU <= #pCPU ты не получишь для одной виртуальной машины.

    ОтветитьУдалить