Я очень хорошо понимаю, как прозрачные огромные страницы работы, и что любое распределение, например, выполненные malloc
может быть удовлетворен огромной страницей.
Я хотел бы знать, есть ли какая-либо проверка, которую я могу сделать (возможно, эвристическая) после выделения, чтобы определить, поддерживается ли память огромной страницей.
Вы можете определить точное состояние любой страницы, включая то, поддерживается ли она прозрачной (или непрозрачной) огромной страницей, просмотрев «pfn» (номер фрейма страницы) в /proc/kpageflags
файл. Вы получаете PFN для страницы, читая из /proc/$PID/pagemap
файл для вашего процесса, который индексируется по виртуальному адресу.
К сожалению, оба pfn
значение от pagemap
1 и весь /proc/kpageflags
Файл доступен только для пользователей root. Тем не менее, если вы можете запустить свой процесс как root по крайней мере в интересующем вас сценарии тестирования или тестирования, это работает хорошо.
Я написал небольшая библиотека под названием page-info который делает соответствующий анализ для вас. Дайте ему диапазон памяти, и он будет возвращать вам информацию на каждой странице, включая то, присутствует ли она в памяти, поддерживается ли она огромной страницей и т. Д.
Например, запуск включенного процесса тестирования как sudo ./page-info-test THP
дает следующий вывод:
PAGE_SIZE = 4096, PID = 18868
size memset FLAG SET UNSET UNAVAIL
0.25 MiB BEFORE THP 0 1 64
0.25 MiB AFTER THP 0 65 0
0.50 MiB BEFORE THP 0 1 128
0.50 MiB AFTER THP 0 129 0
1.00 MiB BEFORE THP 0 1 256
1.00 MiB AFTER THP 0 257 0
2.00 MiB BEFORE THP 0 1 512
2.00 MiB AFTER THP 0 513 0
4.00 MiB BEFORE THP 0 1 1024
4.00 MiB AFTER THP 512 513 0
8.00 MiB BEFORE THP 0 1 2048
8.00 MiB AFTER THP 1536 513 0
16.00 MiB BEFORE THP 0 1 4096
16.00 MiB AFTER THP 3584 513 0
32.00 MiB BEFORE THP 0 1 8192
32.00 MiB AFTER THP 7680 513 0
64.00 MiB BEFORE THP 0 1 16384
64.00 MiB AFTER THP 15872 513 0
128.00 MiB BEFORE THP 0 1 32768
128.00 MiB AFTER THP 32256 513 0
256.00 MiB BEFORE THP 0 1 65536
256.00 MiB AFTER THP 65024 513 0
512.00 MiB BEFORE THP 0 1 131072
512.00 MiB AFTER THP 124416 6657 0
1024.00 MiB BEFORE THP 0 1 262144
1024.00 MiB AFTER THP 0 262145 0
DONE
UNAVAIL
столбец означает, что информация о сопоставлении недоступна — обычно потому, что к странице никогда не обращались и поэтому она вообще не поддерживается какой-либо страницей. Вы можете видеть, что для этих «больших» распределений только одна страница отображается после выделения, так как мы не коснулись памяти.
AFTER
строки представляют собой одну и ту же информацию после вызова memset()
на все распределение, что приводит к физическому распределению всех страниц. Здесь мы можем видеть, что никакие выделения не поддерживаются прозрачными огромными страницами до тех пор, пока мы не достигнем выделения 4 МБ, и в этот момент большая часть каждого выделения поддерживается THP, за исключением 513 страниц (которые оказываются на краях выделенной области). ). При 512 МБ система начинает исчерпывать доступные огромные страницы, но все еще удовлетворяет большую часть выделения, но при 1024 МБ все распределение удовлетворяется небольшими страницами.
Эта библиотека не готова к работе, поэтому не используйте ее для каких-либо критических задач (например, некоторые сбои просто вызывают exit()
). Взносы приветствуются.
1 Начиная с ядра 4.0 приблизительно, до этого pfn был доступен для некорневых пользовательских процессов. С 4.0 до 4.1 или около того, весь pagemap
был закрыт для не-корневых процессов, но с тех пор файл снова доступен, но с маскированным pfn (он всегда будет отображаться как ноль).
Существует разница между традиционными огромными страницами и прозрачными огромными страницами (THP). В случае с THP приложение может использовать огромные страницы без какой-либо поддержки со стороны разработчика (mmap, shmget и т. Д.) Или вмешательства sys-admin.
Боюсь, что в коде не может быть прямого пути проверить это. Однако, если вам известна распределенная структура данных или буферы sizeof (), стоит поискать и проверить использование THP в системе с помощью следующей команды. Это использование должно увеличиться при запуске вашего приложения:
# grep AnonHugePages /proc/meminfo
AnonHugePages: 2648064 kB