Edit: Я обновил свой вопрос с деталями моего тестаКак использовать страницы Intel Westmere 1GB в Linux?
Для целей сравнения, я пытаюсь настроить 1 ГБ страниц в системе Linux 3.13 работает поверх двух Intel Xeon 56xx («Westmere») процессоры , Для этого я изменил параметры загрузки, чтобы добавить поддержку 1 ГБ страниц (10 страниц). Эти параметры загрузки содержат только 1 ГБ страниц, а не 2 МБ. Запуск hugeadm --pool-list
приводит к:
Size Minimum Current Maximum Default
1073741824 10 10 10 *
Мои параметры загрузки ядра будут приняты во внимание. В моем тесте я выделение 1GiB памяти, что я хочу быть подкреплен огромной страницей 1GiB с помощью:
#define PROTECTION (PROT_READ | PROT_WRITE)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
uint64_t size = 1UL*1024*1024*1024;
memory = mmap(0, size, PROTECTION, FLAGS, 0, 0);
if (memory == MAP_FAILED) {
perror("mmap");
exit(1);
}
sleep(200)
Глядя на /proc/meminfo
в то время как скамейка спит (sleep
вызова выше), мы видим, что один огромный страница была выделена:
AnonHugePages: 4096 kB
HugePages_Total: 10
HugePages_Free: 9
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 1048576 kB
Примечание: Я отключил THP (через /sys
файловой системы) перед запуском скамейки, так что я предполагаю, что AnonHugePages
поле сообщает /proc/meminfo
представляет огромные страницы, выделенные ТНР Befo повторно останавливая его.
На этом этапе мы можем думать, что все в порядке, но, к сожалению, моя скамейка заставляет меня думать, что используется много страниц 2MiB, а не одна страница 1GiB. Вот объяснение:
Эта скамья случайным образом получает доступ к выделенной памяти через погоню за указателем: первый шаг заполняет память, чтобы включить преследование цепей (каждая ячейка указывает на другую ячейку), а на втором этапе скамья перемещается по памяти, используя
pointer = *pointer;
perf_event_open
Используя системный вызов, я рассчитываю данные TLB чтения промаха на втором этапе только скамейки. Когда размер выделенной памяти равен 64MiB, я подсчитываю очень небольшое число, 0,01% из моих 6400000 обращений к памяти, данных пропущенных пропусков TLB. Все обращения сохраняются в TLB. Другими словами, 64 Мбайт памяти может храниться в TLB. Как только размер выделенной памяти превышает 64 мегабайта, я вижу, что данные tlb читают промахи. Для размера памяти, равного 128 MiB, у меня есть 50% моих 6400000 обращений к памяти, которые пропустили в TLB. 64MiB представляется размером, который может вписываться в TLB и 64MiB = 32 записи (как указано ниже) * 2MiB-страницы. Я пришел к выводу, что я не использую страницы 1GiB, а 2MiB.
Вы видите какие-либо объяснения этого поведения?
Кроме того, cpuid
инструмента, сообщает следующее о TLB на моей системе:
cache and TLB information (2):
0x5a: data TLB: 2M/4M pages, 4-way, 32 entries
0x03: data TLB: 4K pages, 4-way, 64 entries
0x55: instruction TLB: 2M/4M pages, fully, 7 entries
0xb0: instruction TLB: 4K, 4-way, 128 entries
0xca: L2 TLB: 4K, 4-way, 512 entries
L1 TLB/cache information: 2M/4M pages & L1 TLB (0x80000005/eax):
L1 TLB/cache information: 4K pages & L1 TLB (0x80000005/ebx):
L2 TLB/cache information: 2M/4M pages & L2 TLB (0x80000006/eax):
L2 TLB/cache information: 4K pages & L2 TLB (0x80000006/ebx):
Как вы можете видеть, что нет никакой информации о страницах 1GiB. Сколько таких страниц можно кэшировать в TLB?
Вы можете использовать 'mmap (..., MAP_ANON | MAP_HUGETLB)'? – abligh
@abligh с ошибкой «Не удается выделить память» –
У вас есть огромная поддержка страниц, скомпилированная в ваше ядро? – abligh