Постоянная память (Persistent Memory, PMEM) – это быстрая память, обладающая возможностью хранить данные после отключения питания компьютера. Нередко её называют «Non-Volatile Random Access Memory» (NVRAM) – «энергонезависимой оперативной памятью», или просто «энергонезависимой памятью». Ещё одно наименование такой памяти – NVDIMM. Оно указывает на то, что в состав постоянной памяти входят модули традиционной оперативной памяти.
![](https://habrastorage.org/files/ad2/ef6/b36/ad2ef6b36cfb456d9d064b186ad433f9.jpg)
Иногда мы просто не знаем, какую картинку вставить до ката. И сегодня именно такой случай. Путь будет кот :)
Исторически сложилось так, что приложения организуют данные с использованием двух уровней памяти. Первый – быстрая оперативная память, второй – сравнительно медленные накопители информации. Появление PMEM означает возникновение третьего уровня памяти, занимающего место между первым и вторым.
Работать с новым видом памяти можно так же, как с ОЗУ, используя инструкции процессора по загрузке и сохранению данных.
Путь аппаратных решений, реализующих PMEM, только начинается. Однако, всё указывает на то, что они вполне могут получить широкое распространение. Новая разновидность памяти требует новых подходов к разработке программного обеспечения. Программы сами по себе не могут извлечь выгоду из PMEM, их нужно к этому подготовить.
Если вы – программист, который хочет, как можно раньше, ещё до широкого распространения аппаратных PMEM-решений, приступить к созданию приложений, умеющих работать с новой памятью, вы можете воспользоваться эмуляцией. Такой подход поможет и при обновлении существующих проектов.
Из этого материала вы узнаете о том, как настроить эмуляцию PMEM, используя обычную оперативную память. Выделенная под эмуляцию область ОЗУ будет видна операционной системе как область постоянной памяти. Надо отметить, что в нашем случае, так как эмуляция основана на обычной DRAM, данные из виртуальной PMEM теряются после выключения питания. Однако, скорость работы с эмулируемой памятью будет очень высокой.
Здесь мы будем пользоваться сервером с процессором Intel и ОС семейства Linux с ядром версии 4.3. или выше. Мы расскажем о конфигурировании аппаратного обеспечения, и о том, как настроить программную часть решения. После того, как эмуляция будет настроена, вы сможете испытать примеры PMEM-приложений, которые можно найти в библиотеке NVM на сайте pmem.io.
Вот характеристики аппаратного и программного обеспечения, которые использовались для экспериментов.
В ходе работы использовалось ядро Linux версии 4.5.3. Поддержка устройств постоянной памяти и эмуляции имеется в ядре, начиная с версии 4.0, однако, для того, чтобы упростить настройку системы, рекомендуется пользоваться ядрами версии выше 4.2.
Эмуляция должна работать с любым дистрибутивом Linux, который способен поддерживать официальное ядро. Для того, чтобы установить нужные драйверы, запустите make nconfig.
На рисунках 1 — 5 показан процесс настройки поддержки NVDIMM в меню конфигурации ядра (Kernel Configuration).
![](https://habrastorage.org/getpro/habr/post_images/042/184/eaa/042184eaa1e93a87486c3d20a9a6b21f.jpg)
Рис. 1. Переход к настройке драйверов устройств
![](https://habrastorage.org/getpro/habr/post_images/9d1/406/f66/9d1406f66f6da90015553b02e4547104.jpg)
Рис. 2. Настройка поддержки NVDIMM
![](https://habrastorage.org/getpro/habr/post_images/1ad/482/7ae/1ad4827ae0e7cc179212bdd0cee1087b.jpg)
Рис. 3. Настройка файловой системы для поддержки технологии Direct Access
![](https://habrastorage.org/getpro/habr/post_images/95b/8fa/841/95b8fa841aa693da4adf624c89a2d22a.jpg)
Рис. 4. Настройка поддержки Direct Access (DAX)
![](https://habrastorage.org/getpro/habr/post_images/d92/3f7/35c/d923f735c78c3fe8b1509ef20c54be3f.jpg)
Рис. 5. Параметры поддержки NVDIMM
Ядро предложит области памяти для драйвера PMEM, их можно будет использовать для эмуляции постоянного хранилища. На рисунках 6 — 7 показана настройка параметров процессора и системы.
![](https://habrastorage.org/getpro/habr/post_images/e6c/4d9/1a3/e6c4d91a3022e0352d6ae92830e28324.jpg)
Рис. 6. Настройка процессора для поддержки NVDIMM
![](https://habrastorage.org/getpro/habr/post_images/62f/d6c/5bc/62fd6c5bc64538abc7c9ccb91881c8be.jpg)
Рис. 7. Включение поддержки нестандартной памяти NVDIMM и памяти, защищённой ADR
Теперь всё готово к тому, чтобы собрать ядро, используя команду, показанную ниже.
Новое ядро можно собрать значительно быстрее, используя несколько потоков. Эксперименты с разным количеством потоков показали, что компиляцию можно ускорить примерно на 95% в многопоточном режиме. В результате настройка нового ядра проходит довольно быстро. На двух рисунках, приведённых ниже, показана загрузка процессора и график, иллюстрирующий воздействие на производительность использования нескольких потоков при сборке ядра.
![](https://habrastorage.org/getpro/habr/post_images/748/71f/ac0/74871fac0fc3fdf963e67d6dc059982f.jpg)
Рис. 8. Компиляция исходного кода ядра
![](https://habrastorage.org/getpro/habr/post_images/df3/319/85b/df331985b319b87ca0c6faf2012e0c25.jpg)
Рис. 9. Влияние многопоточности на производительность компиляции
Для установки ядра воспользуйтесь такой командой:
![](https://habrastorage.org/getpro/habr/post_images/2c0/998/e4f/2c0998e4f8e29d34213244fec66d1c5b.jpg)
Рис. 10. Установка ядра
Теперь зарезервируем область памяти, модифицировав загрузочные параметры ядра. В итоге выбранная область будет выглядеть для операционной системы как постоянная память. Здесь используется команда такого вида:
В результате её исполнения будет выделена область памяти в диапазоне от ss до ss+nn. «KMG» – это сокращение для единиц измерения: Kilo, Mega, Giga.
Например, команда вида memmap=4G!12G резервирует 4 Гб памяти между 12-тым и 16-тым гигабайтами. Настройка выполняется в GRUB и различается для разных дистрибутивов Linux. Вот пример конфигурации GRUB для CentOS 7.0.
На рисунке ниже показана инструкция, касающаяся PMEM, добавленная в GRUB-файл.
![](https://habrastorage.org/getpro/habr/post_images/f56/247/924/f56247924b5b679549328adafd357140.jpg)
Рис. 11. Указание областей для PMEM в файле /etc/default/grub
А вот – процесс сборки конфигурации GRUB.
![](https://habrastorage.org/getpro/habr/post_images/6fd/71b/d9b/6fd71bd9b4a9d6d82fb9d9544a9b31fa.jpg)
Рис. 12. Создание файла конфигурации загрузки на основе шаблона grub
После настройки GRUB и перезагрузки компьютера, если всё сделано правильно, можно будет увидеть эмулируемое устройство как /dev/pmem0…pmem3.
Попытка захватить зарезервированные области памяти под эмуляцию постоянной памяти приведёт к разорванным областям, относящимся к постоянной памяти (type 12).
![](https://habrastorage.org/getpro/habr/post_images/a79/ca7/e9e/a79ca7e9ed08433fd59563ad42646436.jpg)
Рис. 13. Области, выделенные под эмуляцию постоянной памяти маркированы как (type 12)
При настройке рекомендуется либо использовать память из диапазона, превышающего 4 Гб (memmap=nnG!4G), либо предварительно проверить карту памяти (через BIOS-e820) и выбрать подходящий диапазон.
Если нужного виртуального устройства в системе не видно, проверьте настройки memmap в файле grub, как показано на рис. 11, затем – проанализируйте состояние памяти с помощью dmesg, как показано на рисунке 13. Если всё настроено правильно, вы увидите зарезервированные области памяти. Здесь могут присутствовать и неперекрывающиеся области, зарезервированные как постоянная память. Если при настройке использовать несколько команд memmap, будут созданы несколько виртуальных устройств, предоставляемых ядром и видимых как /dev/pmem0, /dev/pmem1, /dev/pmem2 и так далее.
Расширения прямого доступа (Direct Access, DAX) к файловой системе создают среду, в которой можно работать с PMEM. Некоторые дистрибутивы, такие, как Fedora 24 и её более поздние версии, уже имеют встроенные механизмы DAX/PMEM, там же доступна и библиотека NVM (NVML).
Вот быстрый способ проверить, встроены ли в ядро DAX и PMEM. Для этого можно обработать утилитой egrep конфигурационный файл ядра, который обычно находится в папке /boot дистрибутива:
В результате выполнения такой команды будет выведено примерно следующее:
С помощью следующих команд можно установить файловую систему с DAX (сегодня это возможно для ext4 и xfs):
Теперь в только что смонтированном разделе можно создавать файлы и передавать в качестве входных данных NVML-пулам.
![](https://habrastorage.org/getpro/habr/post_images/37e/ad4/f95/37ead4f959134e482c348cbb27f0b421.jpg)
Рис. 14. Блоки постоянной памяти
![](https://habrastorage.org/getpro/habr/post_images/06e/12f/e0d/06e12fe0d203c3be8f131e1b5f1bc8ba.jpg)
Рис. 15. Сборка файловой системы
Стоить отметить, что эмулировать постоянную память можно и с помощью ramdisk (то есть, /dev/shm), или установив переменную окружения PMEM_IS_PMEM_FORCE=1. Это позволит избежать воздействия на производительность, вызванного msync.
Теперь вы знаете, как настроить среду, в которой можно создавать приложения, работающие с PMEM, не имея соответствующего аппаратного обеспечения, а используя дополнительные потоки на серверах с архитектурой Intel, вы сможете быстро собрать новое ядро Linux, готовое к экспериментам с постоянной памятью.
![](https://habrastorage.org/files/ad2/ef6/b36/ad2ef6b36cfb456d9d064b186ad433f9.jpg)
Иногда мы просто не знаем, какую картинку вставить до ката. И сегодня именно такой случай. Путь будет кот :)
Исторически сложилось так, что приложения организуют данные с использованием двух уровней памяти. Первый – быстрая оперативная память, второй – сравнительно медленные накопители информации. Появление PMEM означает возникновение третьего уровня памяти, занимающего место между первым и вторым.
Работать с новым видом памяти можно так же, как с ОЗУ, используя инструкции процессора по загрузке и сохранению данных.
Путь аппаратных решений, реализующих PMEM, только начинается. Однако, всё указывает на то, что они вполне могут получить широкое распространение. Новая разновидность памяти требует новых подходов к разработке программного обеспечения. Программы сами по себе не могут извлечь выгоду из PMEM, их нужно к этому подготовить.
Если вы – программист, который хочет, как можно раньше, ещё до широкого распространения аппаратных PMEM-решений, приступить к созданию приложений, умеющих работать с новой памятью, вы можете воспользоваться эмуляцией. Такой подход поможет и при обновлении существующих проектов.
Из этого материала вы узнаете о том, как настроить эмуляцию PMEM, используя обычную оперативную память. Выделенная под эмуляцию область ОЗУ будет видна операционной системе как область постоянной памяти. Надо отметить, что в нашем случае, так как эмуляция основана на обычной DRAM, данные из виртуальной PMEM теряются после выключения питания. Однако, скорость работы с эмулируемой памятью будет очень высокой.
Здесь мы будем пользоваться сервером с процессором Intel и ОС семейства Linux с ядром версии 4.3. или выше. Мы расскажем о конфигурировании аппаратного обеспечения, и о том, как настроить программную часть решения. После того, как эмуляция будет настроена, вы сможете испытать примеры PMEM-приложений, которые можно найти в библиотеке NVM на сайте pmem.io.
Аппаратные и программные компоненты
Вот характеристики аппаратного и программного обеспечения, которые использовались для экспериментов.
Компонент |
Характеристики |
Процессор |
Intel Xeon E5-2699 v4 (2.2 ГГц, 22 ядра, используется одно ядро). |
Чипсет |
Intel C610 QS (степпинг B1), системная шина Intel QPI, 9.6 ГТ/с. |
Платформа |
Intel Server System R2000WT (Wildcat Pass), 24 слота DIMM, 2 процессорных сокета, блок питания на 1100 Вт. BIOS – GRRFSDP1.86B.0271.R00.1510301446 ME:V03.01.03.0018.0 BMC:1.33.8932 |
Оперативная память |
Micron MTA36ASF2G72PZ2GATESIG, 256 Гб (16х16 Гб) DDR4 2133P. |
Накопитель |
Western Digital WD1002FAEX, 1 Тб. |
Операционная система |
CentOS с ядром 4.5.3 |
Подготовка ядра Linux
В ходе работы использовалось ядро Linux версии 4.5.3. Поддержка устройств постоянной памяти и эмуляции имеется в ядре, начиная с версии 4.0, однако, для того, чтобы упростить настройку системы, рекомендуется пользоваться ядрами версии выше 4.2.
Эмуляция должна работать с любым дистрибутивом Linux, который способен поддерживать официальное ядро. Для того, чтобы установить нужные драйверы, запустите make nconfig.
На рисунках 1 — 5 показан процесс настройки поддержки NVDIMM в меню конфигурации ядра (Kernel Configuration).
$ make nconfig
-> Device Drivers -> NVDIMM Support ->
<M>PMEM; <M>BLK; <*>BTT
![](https://habrastorage.org/getpro/habr/post_images/042/184/eaa/042184eaa1e93a87486c3d20a9a6b21f.jpg)
Рис. 1. Переход к настройке драйверов устройств
![](https://habrastorage.org/getpro/habr/post_images/9d1/406/f66/9d1406f66f6da90015553b02e4547104.jpg)
Рис. 2. Настройка поддержки NVDIMM
![](https://habrastorage.org/getpro/habr/post_images/1ad/482/7ae/1ad4827ae0e7cc179212bdd0cee1087b.jpg)
Рис. 3. Настройка файловой системы для поддержки технологии Direct Access
![](https://habrastorage.org/getpro/habr/post_images/95b/8fa/841/95b8fa841aa693da4adf624c89a2d22a.jpg)
Рис. 4. Настройка поддержки Direct Access (DAX)
![](https://habrastorage.org/getpro/habr/post_images/d92/3f7/35c/d923f735c78c3fe8b1509ef20c54be3f.jpg)
Рис. 5. Параметры поддержки NVDIMM
Ядро предложит области памяти для драйвера PMEM, их можно будет использовать для эмуляции постоянного хранилища. На рисунках 6 — 7 показана настройка параметров процессора и системы.
$ make nconfig
-> Processor type and features
<*>Support non-standard NVDIMMs and ADR protected memory
![](https://habrastorage.org/getpro/habr/post_images/e6c/4d9/1a3/e6c4d91a3022e0352d6ae92830e28324.jpg)
Рис. 6. Настройка процессора для поддержки NVDIMM
![](https://habrastorage.org/getpro/habr/post_images/62f/d6c/5bc/62fd6c5bc64538abc7c9ccb91881c8be.jpg)
Рис. 7. Включение поддержки нестандартной памяти NVDIMM и памяти, защищённой ADR
Теперь всё готово к тому, чтобы собрать ядро, используя команду, показанную ниже.
$ make -jX
X – это число ядер процессора
Ускорение сборки ядра
Новое ядро можно собрать значительно быстрее, используя несколько потоков. Эксперименты с разным количеством потоков показали, что компиляцию можно ускорить примерно на 95% в многопоточном режиме. В результате настройка нового ядра проходит довольно быстро. На двух рисунках, приведённых ниже, показана загрузка процессора и график, иллюстрирующий воздействие на производительность использования нескольких потоков при сборке ядра.
![](https://habrastorage.org/getpro/habr/post_images/748/71f/ac0/74871fac0fc3fdf963e67d6dc059982f.jpg)
Рис. 8. Компиляция исходного кода ядра
![](https://habrastorage.org/getpro/habr/post_images/df3/319/85b/df331985b319b87ca0c6faf2012e0c25.jpg)
Рис. 9. Влияние многопоточности на производительность компиляции
Установка и настройка нового ядра
Для установки ядра воспользуйтесь такой командой:
# make modules_install install
![](https://habrastorage.org/getpro/habr/post_images/2c0/998/e4f/2c0998e4f8e29d34213244fec66d1c5b.jpg)
Рис. 10. Установка ядра
Теперь зарезервируем область памяти, модифицировав загрузочные параметры ядра. В итоге выбранная область будет выглядеть для операционной системы как постоянная память. Здесь используется команда такого вида:
memmap=nn[KMG]!ss[KMG]
В результате её исполнения будет выделена область памяти в диапазоне от ss до ss+nn. «KMG» – это сокращение для единиц измерения: Kilo, Mega, Giga.
Например, команда вида memmap=4G!12G резервирует 4 Гб памяти между 12-тым и 16-тым гигабайтами. Настройка выполняется в GRUB и различается для разных дистрибутивов Linux. Вот пример конфигурации GRUB для CentOS 7.0.
# vi /etc/default/grub
GRUB_CMDLINE_LINUX="memmap=nn[KMG]!ss[KMG]"
On BIOS-based machines:
# grub2-mkconfig -o /boot/grub2/grub.cfg
На рисунке ниже показана инструкция, касающаяся PMEM, добавленная в GRUB-файл.
![](https://habrastorage.org/getpro/habr/post_images/f56/247/924/f56247924b5b679549328adafd357140.jpg)
Рис. 11. Указание областей для PMEM в файле /etc/default/grub
А вот – процесс сборки конфигурации GRUB.
![](https://habrastorage.org/getpro/habr/post_images/6fd/71b/d9b/6fd71bd9b4a9d6d82fb9d9544a9b31fa.jpg)
Рис. 12. Создание файла конфигурации загрузки на основе шаблона grub
После настройки GRUB и перезагрузки компьютера, если всё сделано правильно, можно будет увидеть эмулируемое устройство как /dev/pmem0…pmem3.
Попытка захватить зарезервированные области памяти под эмуляцию постоянной памяти приведёт к разорванным областям, относящимся к постоянной памяти (type 12).
![](https://habrastorage.org/getpro/habr/post_images/a79/ca7/e9e/a79ca7e9ed08433fd59563ad42646436.jpg)
Рис. 13. Области, выделенные под эмуляцию постоянной памяти маркированы как (type 12)
При настройке рекомендуется либо использовать память из диапазона, превышающего 4 Гб (memmap=nnG!4G), либо предварительно проверить карту памяти (через BIOS-e820) и выбрать подходящий диапазон.
Если нужного виртуального устройства в системе не видно, проверьте настройки memmap в файле grub, как показано на рис. 11, затем – проанализируйте состояние памяти с помощью dmesg, как показано на рисунке 13. Если всё настроено правильно, вы увидите зарезервированные области памяти. Здесь могут присутствовать и неперекрывающиеся области, зарезервированные как постоянная память. Если при настройке использовать несколько команд memmap, будут созданы несколько виртуальных устройств, предоставляемых ядром и видимых как /dev/pmem0, /dev/pmem1, /dev/pmem2 и так далее.
Расширения прямого доступа к файловой системе
Расширения прямого доступа (Direct Access, DAX) к файловой системе создают среду, в которой можно работать с PMEM. Некоторые дистрибутивы, такие, как Fedora 24 и её более поздние версии, уже имеют встроенные механизмы DAX/PMEM, там же доступна и библиотека NVM (NVML).
Вот быстрый способ проверить, встроены ли в ядро DAX и PMEM. Для этого можно обработать утилитой egrep конфигурационный файл ядра, который обычно находится в папке /boot дистрибутива:
# egrep ‘(DAX|PMEM)’ /boot/config-`uname –r`
В результате выполнения такой команды будет выведено примерно следующее:
CONFIG_X86_PMEM_LEGACY_DEVICE=y
CONFIG_X86_PMEM_LEGACY=y
CONFIG_BLK_DEV_RAM_DAX=y
CONFIG_BLK_DEV_PMEM=m
CONFIG_FS_DAX=y
CONFIG_FS_DAX_PMD=y
CONFIG_ARCH_HAS_PMEM_API=y
С помощью следующих команд можно установить файловую систему с DAX (сегодня это возможно для ext4 и xfs):
# mkdir /mnt/pmemdir
# mkfs.ext4 /dev/pmem3
# mount -o dax /dev/pmem3 /mnt/pmemdir
Теперь в только что смонтированном разделе можно создавать файлы и передавать в качестве входных данных NVML-пулам.
![](https://habrastorage.org/getpro/habr/post_images/37e/ad4/f95/37ead4f959134e482c348cbb27f0b421.jpg)
Рис. 14. Блоки постоянной памяти
![](https://habrastorage.org/getpro/habr/post_images/06e/12f/e0d/06e12fe0d203c3be8f131e1b5f1bc8ba.jpg)
Рис. 15. Сборка файловой системы
Стоить отметить, что эмулировать постоянную память можно и с помощью ramdisk (то есть, /dev/shm), или установив переменную окружения PMEM_IS_PMEM_FORCE=1. Это позволит избежать воздействия на производительность, вызванного msync.
Итоги
Теперь вы знаете, как настроить среду, в которой можно создавать приложения, работающие с PMEM, не имея соответствующего аппаратного обеспечения, а используя дополнительные потоки на серверах с архитектурой Intel, вы сможете быстро собрать новое ядро Linux, готовое к экспериментам с постоянной памятью.
Поделиться с друзьями