Я поймал себя на чувстве, что очень хочу поделиться своим опытом работы с энергонезависимой памятью Intel (Intel Optane Memory или Intel PMem = Persistent Memory).
Для краткости я назову его PMem. Думаю, что несмотря на объем продаж в сотни миллионов долларов, мало кто с ним сталкивался и знает его специфику.
В рамках своей работы я работал над этим довольно долгое время и запускал на нем различные приложения и микро-тесты.
А также добился его эффективного использования, доработав под него клиентские коды.
В принципе, литературы по нему есть масса, по крайней мере, на английском языке, но практические советы и простое и понятное описание его поведения найти непросто, а то и невозможно.
Хочу рассказать, чего от него можно ожидать, особенности его режимов работы в тесной связи с производительностью.
Также объясню, в каких случаях это работает хорошо, а в каких вряд ли оправдает ожидания.
На всякий случай вот главная маркетинговая страница Intel, посвященная этой технологии.
На данный момент выпущено уже два поколения PMem (100-я серия и 200-я серия).
100-я серия работает с процессорами Xeon Scalable 2-го поколения (Cascade Lake), а 200-я серия — с 3-го поколения (Ice Lake).
Это все серверные платформы.
В его основе лежит та же технология Optane, которая впервые появилась в твердотельных накопителях (Intel Optane SSD).
Диски, кстати, очень быстрые по сравнению с обычным 3DNAND. Время отклика у них как минимум в 5 раз лучше, а на деле – в 10-20 и более раз.
Это связано с тем, что производительность зависит от нагрузки.
Диски Optan хорошо работают практически при любой нагрузке, сохраняя время отклика практически стабильным на уровне 8 микросекунд (в последнем поколении оно, кажется, даже сократилось), и даже при небольшом количестве потоков, записывающих или читающих из них, их пропускная способность приближается к 100%.
3DNAND выглядит заметно слабее.
Ему нужны десятки потоков, чтобы что-то отдаленно напоминающее максимальную пропускную способность материализовалось в реальности.
В этом случае время отклика естественным образом выходит за рамки 100 микросекунд. Однако при чтении большими блоками с достаточным количеством потоков оба диска будут давать схожие результаты по пропускной способности.
Фактически у топовых твердотельных накопителей дело зачастую ограничивается их подключением PCIe (обычно им выделяется две линии).
С переходом на PCIe 4 в последнем поколении платформ/процессоров (тех самых Ice Lake) Intel сразу же выпустила накопители с удвоенной пропускной способностью.
Но вернемся к памяти.
Это те же матрицы, что и DDR.
Рисунок 1. Модуль PMem Фактически, DDR необходима для работы системы.
Типичная конфигурация — 1 модуль DDR и 1 PMEM на канал памяти, но в целом возможно множество вариантов.
То есть в сервер Ice Lake с двумя процессорами можно установить модули DDR 2x8 и модули PMEM 2x8. Объем памяти одного модуля составляет 128, 256 или 512 ГБ.
Думаю, именно это объясняет, почему многие читатели до сих пор не столкнулись с этим воспоминанием.
Хотя это гораздо дешевле, чем DDR за гигабайт, при таких объёмах ценники всё равно серьёзные.
Имея 512 модулей в двухпроцессорном сервере, вы можете получить 8 ТБ PMEM плюс еще один DDR. Популярное соотношение — 8:1, при этом общий объём составит 9ТБ, но сложить не всегда получится, и об этом я вам расскажу.
Если очень грубо сравнить производительность PMem и DDR, то PMem примерно в три раза медленнее.
Это касается как времени доступа, так и пропускной способности.
Но есть много разных нюансов.
Для доступа на чтение фактор три работает очень хорошо, но при добавлении даже небольшого количества записи картина резко усложняется и не в пользу PMem. Есть причины такого поведения.
Контроллер памяти PMem (входящий в состав каждого модуля) работает блоками по 256 байт. Он имеет крохотный буфер, в который изначально поступают данные (в случае записи).
Если, например, в этот буфер поступило несколько строк кэша, и некоторые из них соседние (допустим, два потока писали, каждый последовательно - соседи будут по-любому, но не обязательно по порядку), то контроллер будет поменяйте их местами и, возможно, сможете дополнить их блоками по 256 байт, чтобы писать с максимальной эффективностью.
Понятно, что если потоков много, то шансы резко падают, буферы очень скромного размера.
Подозреваю, что увеличить его проблематично, сложность растёт нелинейно и контроллер может с этим не справиться.
Другая сторона проблемы — работа механизма вытеснения строк кэша.
Когда мы что-то записываем в память, то фактически оно не попадает туда сразу, а висит в кеше (запись через кеш).
Затем эта строка кэша будет ждать, пока не придет ее очередь вытеснить.
Процесс непредсказуем, и соседние строки кэша, записанные подряд, могут быть вытеснены в разное время.
Соответственно, даже при последовательной записи в PMem мы получаем случайную, а буфер размером 256 байт работает лишь частично заполненным (возможно, только на четверть, то есть с одной строкой кэша).
Есть два варианта решения этой проблемы, но в обоих случаях для их реализации придется редактировать код. Первый — вызвать инструкцию clflush/clflushopt, чтобы немедленно сбросить строку кэша в память.
Это не бесплатно, но имеет дополнительный бонус.
Это гарантирует сохранение данных в постоянной памяти.
То есть они переживут отключение электроэнергии.
Второй вариант — использовать запись NT (невременную запись).
Это инструкции для записи напрямую, минуя кэш.
Отличная вещь для PMem, гарантирует существенно более высокую производительность и живучесть (нужен только барьер записи).
Но есть одно НО.
Данные не кэшируются.
То есть, если они будут использоваться сразу после этой записи, их придется загружать из памяти.
Это не всегда приемлемо, но все же может быть более продуктивным вариантом.
Я уже говорил, что чтение работает гораздо лучше, добавлю, что пропускная способность при чтении выше как минимум в 2,5 раза, а при менее оптимальном количестве потоков может быть и в 5-6 раз выше.
Еще один интересный нюанс — запись 100-го и 200-го поколений масштабируется совершенно по-разному.
В сотых оно сначала заметно растет с 1 до 4-8 потоков, а затем очень плавно падает. У 200-го максимум достигается за один поток.
В абсолютных цифрах это около 23 ГБ/сек на запись и 55 ГБ/сек на чтение.
Это данные для одного сокета, два дадут в два раза больше.
Если объединить сокеты в один диск с помощью SW RAID, то получится не два, а всего около 1,5, если не меньше.
Как ни странно, такая неважная (даже отрицательная) масштабируемость — это неплохо.
Есть масса приложений, которые особо не оптимизированы, где потоков записи мало, а то и один.
И они просто подружатся с ПМ.
Конфигурация чередования памяти по умолчанию — чередование для всех модулей памяти сокета.
Соответственно достигается максимальный параллелизм и производительность.
Чередование не работает между сокетами.
При желании вы можете настроить каждый модуль самостоятельно, но это безумие, так как писать его придется параллельно на уровне приложения.
Я не могу представить никого, кому это может быть полезно.
Теперь давайте обсудим варианты конфигурации.
На высшем уровне их два — 1LM (одноуровневая память) и 2LM (двухуровневая память).
Во втором случае операционной системе виден только PMem как память, тогда как DDR скрыт на втором уровне и работает как кеш для PMem (прямой кеш).
При этом PMem не является энергонезависимым, то есть данные не сохранятся при перезагрузке.
Обычно речь идет о том, чтобы получить больше памяти, чем это возможно при использовании DDR, или получить тот же объем, но существенно дешевле.
Рисунок 2. Конфигурация 2LM Преимущество этой конфигурации в том, что приложению вообще не нужно ничего знать о памяти.
Это просто сработает. Более того, если данные используются неоднократно, есть большая вероятность, что они будут храниться в основном в DDR, и производительность приложения может быть почти такой же хорошей, как и в случае только с DDR. То есть вы можете иметь и использовать нереально огромную память и при этом работать с производительностью DDR. Отличным примером являются базы данных в памяти.
Как правило, они демонстрируют производительность 90-100% по сравнению с аналогичной системой, оснащенной только DDR. Эта конфигурация также имеет недостатки.
Во-первых, DDR практически недоступна для данных.
То есть напрямую в нем нет возможности аллокировать.
Во-вторых, это самый низкопроизводительный мод для PMem. Время доступа в DDR прибавляется ко времени доступа и пропускная способность в разы ниже (~4-5 раз), чем у 1LM. Приложения вычислительного типа имеют мало шансов на успех.
1LM — гораздо более интересный мод. Здесь есть варианты.
По производительности самого PMem они практически схожи (максимум), но имеют принципиальные различия, не связанные с аппаратной частью.
Все опции относятся к типу AppDirect. Смысл этого термина в том, что приложение как бы напрямую заботится о взаимодействии с ПМ, хотя на самом деле в этом нет необходимости.
Рисунок 3. Конфигурация 1LM Первый вариант — «Хранилище через AppDirect».
Фактически в такой конфигурации мы получаем диск на ПМЕМ с файловой системой.
Самый простой случай — настройка обычного блочного диска.
То есть поблочный доступ.
Небольшой недостаток - время доступа, блок есть блок.
Нужна строка кэша — все равно загружайте 4К.
Но есть и серьезные преимущества.
Во-первых, приложения, требующие ускорения ввода-вывода, не потребуют никаких изменений.
Просто переключитесь на диск PMEM. Во-вторых, в этом случае сама операционная система автоматически кэширует страницы с диска в память.
Как только со страницы считывается единица данных, операционная система загружает всю страницу в DDR. То есть следующие данные с этой страницы будут поступать из DDR. Для последовательного доступа (а его много) это прекрасно работает. На мой взгляд, эта конфигурация самая универсальная и сбалансированная.
Превосходит любую из самых быстрых систем хранения с большим отрывом (обычно в 2-7 раз) практически в любом тесте чтения.
Рисунок 4. Конфигурация 1LM Storage через AppDirect Второй вариант — это то же Storage over AppDirect, но смонтированное в режиме DAX (прямой доступ).
Для этого мода требуется файловая система, которая может работать с PMem, в частности, обеспечивая доступ через строки кэша.
Проблем с этим уже давно не было; любая современная операционная система поддерживает его.
С точки зрения производительности разница по сравнению с хранилищем через AppDirect значительна.
Во-первых, гранулярность доступа к одной строке кэша сокращает время доступа в несколько раз.
То есть произвольный доступ просто полетит по сравнению с любыми дисками и системами хранения данных.
Как вам ускорение в 100 раз, например? Вполне реальная цифра.
Недостаток такой конфигурации в том, что операционная система больше не участвует и не кэширует страницы в DDR. То есть все, что было выделено в PMem, оттуда пойдет напрямую в кэш процессора.
В такой конфигурации PMem дико ломает любую самую быструю систему хранения данных на произвольном доступе, но в случае последовательного доступа с повторным использованием данных он не всегда выиграет. Как и в предыдущем случае, нет необходимости модифицировать приложение, если целью является ускорение ввода-вывода.
Это если в основном читать; если записи много, то для исполнения потребуются модификации.
И, наконец, третий вариант — AppDirect Volatile. В этом случае PMem используется как энергозависимая память.
Производительность очень близка к DAX и даже немного лучше, поскольку файловой системы больше нет. О работе с файлами речи уже не идет; PMem виден именно как память.
Задача разработчика — правильно разместить данные (и написать с правильными инструкциями).
Небольшие и динамические данные передаются в DDR, а большие и более статические данные — в PMem. Если в процессе работы приложения возникает необходимость переместить данные из одного типа памяти в другой, приложение должно это сделать (то есть об этом должен позаботиться разработчик кода).
PMem виден как дополнительный NUMA-узел, поэтому написать распределитель не составит труда.
Еще одним интересным фактом является то, что вы можете настроить комбинацию этих опций, например часть 1LM и часть 2LM. Или создайте на PMem две файловые системы: одну обычную, а другую с прямым доступом.
Или оба одновременно.
Одним словом, есть простор для творчества.
Что еще вам нужно знать о PMem? Если погуглить Intel PMem, то сразу всплывает ПМДК .
Это набор библиотек, позволяющих эффективно работать с PMem на разных уровнях.
Основная идея PMDK — помочь разработчику работать грамотно (транзакционно) с персистентностью.
То есть с помощью своих библиотек обеспечить согласованность данных (либо транзакция полностью сохраняется в постоянной памяти, либо не сохраняется вообще, но не частично).
Это можно сделать от одной переменной до транзакций высокой сложности.
По сути, эти механизмы очень похожи на синхронизацию потоков и без них потребовалась бы очень кропотливая работа и дорогостоящая отладка.
Если вы прочтете документацию PMDK, у вас может сложиться впечатление, что без него никуда, но это не так.
Даже если приложение работает не с файлами, а с памятью, использовать такие опции, как Storage over AppDirect (то есть с постоянством), совсем не сложно.
Для этого достаточно открыть файл, сделать для него карту памяти и поместить в этот файл все данные, которые идут в PMem. При этом разработчик сам выбирает, какие инструкции писать в PMem, и обеспечивает согласованность данных по тем же общим принципам, что и в многопоточных приложениях.
ПМДК делает то же самое.
Как я уже говорил, чтение гораздо продуктивнее и стабильнее, чем письмо.
Запись более капризна, требует правильной инструкции и имеет умеренно негативное масштабирование.
Это обстоятельство часто приводит к ситуации «неоправданных надежд» у клиентов, впервые попробовавших PMem, не трогая приложение.
Проблема в том, что использование стандартного ввода-вывода операционной системы ни в коем случае не оптимизировано для PMEM и зачастую производительность аналогична твердотельному диску.
По моему опыту, типичное ускорение при переходе на PMEM (если брать только ввод-вывод) составляет от 3,5 до 6 раз в ситуациях интенсивной записи.
Это сравнивается с одним SSD и использованием правильных инструкций.
У нас есть несколько инструментов и методик для точного тестирования без изменения приложения, но это отдельная тема.
Интересная проблема — определение данных для размещения в DDR или PMem. Методы понятны, а характеристики данных можно измерить, например, с помощью VTune Performance Analyser. Но опять же, по моему опыту, вариантов приложений вычислительного типа, которые будут хорошо работать в этом режиме, очень мало.
Базы данных и другие приложения для обработки больших данных — практически единственное работающее направление.
В большинстве приложений вычислительного типа значительная часть данных должна быть как прочитана, так и записана, а запись приводит к такому ухудшению производительности ПМ, что ПМ становится нерентабельным.
В общем, если совсем коротко, то так.
Если мы говорим о замене любой из лучших диких систем хранения данных и главным фактором является производительность, то Pmem — это находка.
Огромный объем за гораздо меньшие деньги, чем DDR, хорошая производительность.
В том случае, когда вам в основном нужно прочитать данные, и часто ничего делать не нужно.
Ну а если записи много, то работать придется, и результат наверняка будет не звездным.
Здесь вам придется оценить цены по сравнению с производительностью.
Если приложение вычислительного типа, то вариантов использования PMem пока немного.
Скорее всего, будут большие объемы статических данных, которые необходимо будет часто загружать для вычислений.
Теги: #сервер #Intel #Хранение данных #Высокая производительность #Большие данные #Анализ и проектирование систем #производительность #Оптимизация клиента #Конфигурация #энергонезависимая память
-
Основы Дешевого Android-Планшета
19 Oct, 24 -
Как Adobe Обновит Flash До Версии 10
19 Oct, 24 -
Какие Документы Люди Пытаются Купить Онлайн?
19 Oct, 24 -
Игра Окончена, Ребята
19 Oct, 24 -
Какой-То Праздник...
19 Oct, 24 -
Интересные Кадры С Google Maps. Продолжение
19 Oct, 24