SMP: Режим NUMA
Вопрос к счастливым обладателям 2-х процессорных серверов. (Если процессоров больше, то там все однозначно)
В каких случаях есть смысл включать в БИОСе режим NUMA и использовать ядра с поддержкой NUMA?
Есть ли какие-то категории задач которые в режиме NUMA дают прирост общей производительности системы или наоборот получается падение общей производительности системы ?
Так если несколько отдельных процессоров каждый со своей памятью это в любом случае numa, не? А переключение это какой-нибудь костыль для венды.
Включаем, т.к. оно включено по дефолту =)
Отключать вряд ли имеет смысл, разве что подкрутить NUMA Group Size Optimization для не NUMA-aware софта, если того рекомендует вендор.
Во-первых, сейчас честных SMP не осталось в природе от слова совсем.
Во-вторых, что касается указанной настройки, так это сделано для венды, т.к. там есть такой костыль как Kernel Groups (Kgroups). Изначально венда умела только 64 логических процессора. Потом, чтобы это обойти придумали эти самые группы, каждая из которых имела аналогичное ограничение, зато самих группы было уже несколько. Так вот какой-то старый софт немного не в курсе, а потому продолжает жить в пределах одной группы. Это приводит к невозможности задействовать все ядра, а потому нужно настройку NUMA отключать, иначе венда криво формирует группы. Как-то так. Можно почитать всякую ерунду типа Microsoft KBA 2506384.
Мне думается, что для линукса это неактуально. А потому поддержу предыдущего оратора, рекомендующего всё включить. Пусть БИОС сообщает труЪ ОСи правду.
Я думал, что настройка в биосе как-то влияет на настройки контроллера памяти.
Теоретически оно должно было влиять на скорость работы процессора со своей памятью и «чужой», что подтверждалось в одной статье опубликованной несколько лет назад. Правда там тестирование велось под оффтопиком.
Пока машина находится на стадии тестирования есть возможность менять настройки.
Я нашел у интела утиль для имерения скорости работы с памятью, т.ч. можно посмотреть на реальные цифры.
Если бы можно было вишмастетром убрать недостаток медленного доступа к чужой памяти думаешь кто-то бы заморачивался работать без него?
Эта настройка не ускоряет доступ к памяти, она тормозит его всем, чтоб одинаковый был (ака синхронный режим работы кэша(шины?), тот еще гемморой, -5/15% производительности для задач которым безразлична NUMA/которые для нее сделаны и очень маленький прирост приложениям неумеющим в нее)
Есть утиль mlc с intel.com
Первый запуск — NUMA в биосе отключена, ядро ничего не знаяет про NUMA
Второй запуск — NUMA в биосе включена и в ядре включены
Результаты в режиме NUMA отмечены ‘>‘
Полезность режима NUMA для меня пока не очень очевидна.
в п.3 получется дикий провал производительности при обращении в чужую память.
Но пункты 2 и 4 показывают повышение производительности со своей памятью +25%
Может я чего не замечаю ?
Второй пункт с 76654.6 до 96624.9 вырос, а это грубо говоря +25% к общей пропускной способности при условии лазания в локальную для ноды память память.
да, это хорошо, но 5-ти кратное падение скорости в п.3 меня сильно удивило.
Т.е. если планировщик не будет допускать запуска процесс на чужой ноде, то все должно быть лучше чем в UMA режиме.
Источник
NUMизматика, NUMерология и просто о NUMA
Три Богатыря
И начнем с отрицания отрицания. То есть, посмотрим на Uniform Memory Access (Однородный доступ к памяти), известный также так SMP (Symmetric Multi Processing – Симметричная Многопроцессорная Обработка).
SMP – это архитектура, в которой процессоры соединены с общей системной памятью при помощи шины или подобного соединения)симметрично, и имеют к ней равный однородный доступ. Именно так, как показано на схеме ниже (на примере двух CPU), были устроены все многопроцессорные машины Intel, когда контроллер памяти (MCH/MGCH), больше известный как «Северный Мост» (“NorthBridge”) находился в чипсете.
Недостаток SMP очевиден — при росте числа CPU, шина становится узким местом, значительно ограничивая производительность приложений, интенсивно использующих память. Именно поэтому SMP системы почти не масштабируются, два-три десятка процессоров для них – это уже теоретический предел.
Альтернатива SMP для производительных вычислений – это MPP (Massive Parallel Processing).
MPP — архитектура, разделяющая систему на многочисленные узлы, процессоры в которых имеют доступ исключительно к локальным ресурсам. MPP прекрасно масштабируется, но не столь прекрасно программируется. А именно — не обеспечивает встроенного механизма обмена данными между узлами. То есть, реализовывать коммуникации, распределение и планировку задач на узлах должен выполняемый на MPP софт, что подходит далеко не для всех задач и их программистов.
И, наконец, NUMA (Non-Uniform Memory Access). Эта архитектура объединяет положительные черты SMP и MPP. NUMA система разделяется на множественные узлы, имеющие доступ как к своей локальной памяти, так и к памяти других узлов (логично называемой «удаленной»). Естественно, доступ к удаленной памяти оказывается гораздо медленнее, чем к локальной. Оттуда и название – «неоднородный доступ к памяти». Это – не только название, но и недостаток архитектуры NUMA, для смягчения которого может потребоваться специальная оптимизация софта, о которой — дальше.
Вот как выглядит двухсокетная NUMA система Intel Xeon (а именно там дебютировала Intel NUMA) с контроллерами памяти, интегрированными в CPU.
Процессоры здесь соединены QPI — Intel QuickPath соединением «точка-точка» с высокой пропускной способностью и низкой задержкой передачи.
На рисунке не показан кеш процессоров, но все три уровня кеш памяти, конечно же, там есть. А значит, есть и особенность NUMA, о которой необходимо сказать: NUMA, используемая в системах Intel, поддерживает когерентность кешей и разделяемой памяти (то есть, соответствие данных между кешами разных CPU), поэтому ее иногда называют ccNUMA — cache coherent NUMA. Это означает наличие специального аппаратного решения для согласования содержимого кешей, а также и памяти, когда более чем один кеш хранит одну и ту же ее часть. Конечно, такое общение кешей ухудшает общую производительность системы, но без него программировать систему с непредсказуемым текущим состоянием данных было бы крайне интересно затруднительно. Для уменьшения влияния этого эффекта, следует избегать ситуаций, когда несколько процессоров сразу работают с одним блоком памяти (не обязательно с одной переменной!). Именно так и пытаются поступить продукты, поддерживающие NUMA.
Таким образом, от железа мы плавно перешли к программному обеспечению и производительности NUMA систем.
Итак, NUMA поддерживается следующими OS:
Windows Server 2003, Windows XP 64-bit и Windows Vista – до 64 логических процессоров,
Windows 7, Windows Server 2008 R2 – полная поддержка.
Linux OS kernel: 2.6 и выше, UNIX OS — Solaris и HP-Unix.
Если говорить о базах данных, то NUMA поддерживается Oracle8i, Oracle9i, Oracle10g и Oracle11g, а также SQL Server 2005 и SQL Server 2008.
Поддержка NUMA реализована и в Java SE 6u2, JVM 1.6, а также .NET runtime на вышеупомянутых версиях Windows.
Полностью поддерживает NUMA математическая библиотека Intel – MKL.
«Поддержка NUMA» означает следующее – продукт знает о топологии NUMA машины, на которой исполняется, и пытается использовать ее максимально эффективно, то есть, организовать работу потоков так, чтобы они в полной мере использовали память своего узла (того, на котором исполняется данный поток) и минимально – чужих. Ключевое слово здесь – «пытается», так как сделать это в общем случае возможно не всегда.
Поэтому может случиться, что продукт, не поддерживающий NUMA, то есть, просто не знающий о ней, что совсем не мешает ему запускаться и исполняться на NUMA-системах, покажет не худшую производительность, чем официально поддерживающий NUMA. Пример такого продукта — знаменитая библиотека Intel Threading Building Blocks.
Именно поэтому в BIOS мультисокетных серверов с NUMA есть специальный пункт «Разрешить\запретить NUMA». Конечно же, от запрета NUMA в BIOS топология системы никак не изменится — удаленная память не приблизится. Произойдет только следующее – система не сообщит ОС и ПО о том, что она NUMA, а значит, распределение памяти и планировка потоков будут «обычными», такими как на симметричных многопроцессорных системах.
Если BIOS разрешает NUMA, то операционная система сможет узнать о конфигурации NUMA узлов из System Resource Affinity Table (SRAT) в Advanced Configuration and Power Interface (ACPI). Приложения могут получить такую информацию, используя библиотеку libnuma в Linux, а сами понимаете, на каких системах — Windows NUMA interface.
Эта информация – начало поддержки NUMA вашим приложением. За ним должна следовать непосредственно попытка максимально эффективно использовать NUMA. Общие слова на эту тему уже сказаны, для дальнейших пояснений перейду к частному примеру.
Допустим, вы выделяете память при помощи malloc. Если дело происходит в Linux, то malloc только резервирует память, а ее физическое выделение происходит только при фактическом обращении к данной памяти. В этом случае память автоматически выделится на том узле, который ее и использует, что очень хорошо для NUMA. В Windows же malloc работает по-другому, он выделяет физическую память непосредственно при аллоцировании, то есть, на узле выделяющего память потока. Поэтому она вполне может оказаться удаленной для других потоков, ее использующих. Но есть в Windows и дружественное к NUMA выделение памяти. Это VirtualAlloc, который может работать точно также, как malloc в Linux. Еще более продвинутый вариант — VirtualAllocExNuma из Windows NUMA API.
Следующий простой пример, использующий OpenMP,
можно подружить с NUMA, обеспечив инициализацию данных каждым потоком, вызывающую соответствующую привязку физической памяти к использующему ее узлу:
Отдельным пунктом здесь надо упомянуть Affinity — принудительную привязку потоков к конкретным процессорам, предотвращающую возможную переброску операционной системой потоков между процессорами и могущую вызвать потенциальный «отрыв» потоков от своей используемой локальной памяти.
Для установки Affinity имеются соответствующие API как в Linux, так и в Windows ( стандартный Windows API, и NUMA WinAPI). Также функциональность для установки привязки присутствуют во многих параллельных библиотеках (например, в показанном выше примере OpenMP за это отвечает переменная окружения KMP_AFFINITY ).
Но надо понимать, что во-первых, affinity срабатывает не всегда (для системы это, скорее, намек, чем приказ), а во-вторых, положительный эффект от установки Affinity будет только в том случае, когда вы полностью контролируете систему, то есть, на ней работает исключительно ваше приложение, а сама ОС не сильно нагружает систему. Если же, как это чаще всего бывает, приложений несколько, причем, они интенсивно используют CPU и память, пытаясь при этом привязаться к одному процессору, ничего не зная друг о друге, да и ОС конкурирует за те же ресурсы, то от использования Affinity может быть больше вреда, чем пользы
Производительность.
1.7x доступа к локальной памяти, а пропускная способность локальной памяти может быть до двух раз больше, чем удаленной»
Данные реального сервера на Xeon 5500 приводятся в техническом описании Dell -“задержка доступа к локальной памяти составляет 70 наносекунд, к удаленной – 100 наносекунд (т.е.
1.4 раза), пропускная способность локальной памяти превосходит удаленную на 40% ”.
На вашей реальной системе эти приблизительные данные могут быть получены при помощи бесплатной утилиты Microsoft Sysinternals — CoreInfo, оценивающей относительную «стоимость» доступа к памяти разных узлов NUMA. Результат, конечно, сильно приблизительный, но некоторые выводы сделать позовляет.
Пример результата Coreinfo:
Но главный вопрос, это насколько разница в «стоимости» доступа к NUMA памяти скажется на производительности реального приложения в целом. При подготовке этой статьи мне попался очень интересный пост специалиста по SQL Linchi Shea, оценивающий влияние NUMA на производительность SQL Server.
Измерения проводились на HP ProLiant 360 G7 с двумя Intel Xeon X5690, дающими в сумме 12 процессоров (24 логических CPU) и представляли собой сравнение двух сценариев работы Microsoft SQL Server 2008 R2 Enterprise X64:
- Использование исключительно локальной памяти (все запросы обрабатываются на первом NUMA узле, в памяти которого лежит тестовая таблица)
- Использование исключительно удаленной памяти (все запросы обрабатываются на втором узле NUMA, с использованием той же таблицы в памяти первого узла.
Тест выполнен исключительно технически грамотно, так что сомневаться в его достоверности не приходится. За деталями отошлю к исходному посту Linchi (на английском).
Здесь же приведу результаты – оценку количества обработки запросов во времени для обоих сценариев:
Как видите, разница составляет всего чуть более 5%! Результат приятно удивительный. И это – случай максимальной разницы, достигаемый при 32 одновременно работающих потоках с запросами (при другом количестве потоков разница еще меньше).
Так нужно ли оптимизировать для NUMA? Зайду издалека. Хотя у меня нет времени убираться дома, зато есть время читать советы по уборке :). И один из полезных, виденных мной советов такой — чтобы меньше убираться, надо избежать потенциального беспорядка, для чего старайтесь хранить все вещи как можно ближе к месту их использования.
Теперь замените «вещи» на «данные», а «квартиру» на «программу» и увидите один из способов достичь порядка в ваших программах. Но это как раз и будет NUMA-оптимизация, о которой вы сейчас и прочли.
Источник