Подтвердить что ты не робот

Как выделить "огромные" страницы для приложения С++ в Linux

У меня есть приложение С++ для Linux, которое очень чувствительно к задержкам. Мое использование памяти составляет около 2 ГБ, поэтому с 4kb-страницами и 64 записями TLB я собираюсь встретить пропуски TLB.

Я читал в руководствах разработчиков Intel, что "огромные" страницы размером 2 МБ (или 4 МБ?) уменьшают количество записей TLB наполовину, поэтому увеличение диапазона памяти компенсирует сокращение записей в TLB, и было бы лучше для производительности.

Как распределить память с помощью "огромных" страниц в приложении на С++? Есть ли компромиссы, о которых я должен знать?

Мой Linux - это дистрибутив Red Hat.

4b9b3361

Ответ 1

Я предполагаю, что вам нужны огромные страницы только для конкретного приложения, написанного на С++, иначе вы просто измените размер страницы своей системы. Ниже метод будет отлично работать для приложений, написанных на любом языке.

  • Чтобы использовать огромные страницы для конкретного приложения, вам нужно построить ядро ​​для поддержки огромной поддержки страниц. вы должны создать ядро ​​с параметрами CONFIG_HUGETLBFS

  • Укажите размер страницы, указав

    hugepagesz=<size>
    

    в командной строке загрузки

  • Чтобы узнать, как установить параметры загрузки: http://www.cyberciti.biz/tips/10-boot-time-parameters-you-should-know-about-the-linux-kernel.html

  • Чтобы установить no из огромных страниц, используйте

    # echo 20 > /proc/sys/vm/nr_hugepages
    
  • Чтобы проверить огромные страницы (доступные, итоговые,...)

    # cat /proc/meminfo
    
  • Когда все выше будет хорошо, теперь вам нужно работать с "как использовать эти страницы для конкретного приложения": монтировать файловую систему типа hugetlbfs как

    # mount -t hugetlbfs -o uid=<value>,gid=<value>,mode=<value>,pagesize=<value>,size=<value>,min_size=<value>,nr_inodes=<value> none /mnt/huge
    

    разместите приложение на этом жестком диске /mnt/huge теперь ваше приложение будет использовать размер страницы, заданный вами!

Подробнее см. https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt

Достоинства/недостатки огромных страниц:

Эффективность

: благодаря сокращению пропусков TLB, меньшим ошибкам страницы, уменьшению размера таблицы страниц и меньшему количеству переводов

demerits: больше внутренней фрагментации: потеря памяти, большая латентность при обмене (hugetlbfs страницы не изменяются, их отображение постоянно) для более подробной информации проверьте https://lwn.net/Articles/359158/

ИЗМЕНИТЬ Существует также API, позволяющий выделять огромные страницы PLZ-check, возможно, помогает

https://github.com/libhugetlbfs/libhugetlbfs/blob/master/HOWTO

https://lwn.net/Articles/375096/

Ответ 2

Документация "hugetlb" из ядра должна здесь помочь.

Пользователи могут использовать огромную поддержку страниц в ядре Linux, используя либо системный вызов mmap, либо стандартные системные вызовы системной памяти SYSV (shmget, shmat).

и

Примеры

1) map_hugetlb: см. инструменты/тестирование/selftests/vm/map_hugetlb.c

2) greatpage-shm: см. инструменты/тестирование/selftests/vm/vastpage-shm.c

3) largepage-mmap: см. инструменты/тестирование/selftests/vm/vastpage-mmap.c

4) Библиотека libhugetlbfs (https://github.com/libhugetlbfs/libhugetlbfs)   предоставляет широкий спектр средств пользовательского пространства, чтобы помочь с огромной страницей > удобство использования,    настройки среды и управления.

(Эти пути относятся к дереву источника Linux).

Итак, это в основном сводится к:

  • использовать mmap с флагом MAP_HUGETLB
  • или, сопоставьте файл из установленной файловой системы hugetlb, если он существует

Ответ 3

Вы также можете попытаться использовать прозрачную огромную поддержку страниц, которая доступна на любом ядре за последние несколько лет (по крайней мере, что-либо в 3.x и 4.x, а также различные ядра 2.6.x).

Основное преимущество заключается в том, что вам не нужно создавать какие-либо специальные "hugetlbfs", они "просто работают". Недостатком является то, что он гарантирован: ядро ​​может удовлетворить ваши распределения огромными страницами, если выполняются некоторые условия, а некоторые доступны. В отличие от hugetlbfs, который резервирует фиксированное количество огромных страниц при запуске, которые доступны только через определенные вызовы, прозрачные огромные страницы вырезают огромные страницы из общего пула памяти. Для этого требуются смежные 2 МБ блоки физической памяти, которые со временем могут стать редкими из-за фрагментации физической памяти.

Furhtermore, существуют различные настройки ядра, которые влияют на получение огромной страницы или нет, наиболее важным из которых является /sys/kernel/mm/transparent_hugepage/enabled.

Лучше всего выделить блоки на границе 2 МБ с помощью posix_memalign, а затем сделать madvise(MADV_HUGEPAGE) в выделенной области до, касаясь ее в первый раз, Он также работает с такими вариантами, как aligned_alloc. По моему опыту, в системах с /sys/kernel/mm/transparent_hugepage/enabled, установленными на always, это обычно приводит к огромной странице. Тем не менее, я в основном использую системы со значительной свободной памятью и не слишком долгое время.

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

Я также написал библиотеку, чтобы определить, действительно ли вы получили огромные страницы из любого заданного распределения. Вероятно, это не полезно в производственном приложении, но это может быть полезной диагностикой, если вы идете по пути использования THP, поскольку по крайней мере вы можете определить, получили ли вы их или нет.