Чтобы установить соответствующий linux-headers
образ ядра, получите доступный linux-headers
через:
apt-cache search linux-headers
Затем установите:
apt-get install linux-headers-4.9.0-kali4-amd64
Для Linux, как программист, вы, вероятно, захотите использовать libhugetlbfs
, который позаботится обо всем для вас под капотом. (Примечание :Может даже и не потребуется, точно не знаю, надо еще протестировать ).
Он заменяет все функции, управляющие памятью, собственной версией, которая автоматически переключается на огромную страницу, если/когда это возможно. Это будет включать malloc()
и mmap()
и другие, такие как fork()
, выделяющие стек.
В Ubuntu вы можете установить библиотеку следующим образом:
sudo apt-get install libhugetlbfs-dev
Затем вы можете использовать такие функции, как get_huge_pages()
, если вы определенно хотите выделить большой буфер на огромной странице. Это эквивалентно malloc()
. С установленной библиотекой у вас должны быть справочные страницы, поэтому для получения подробной информации вы можете сделать:
man get_huge_page
Существует также функция ОС, mincore()
, которая позволяет получить количество больших страниц и маленьких (4K )страниц, используемых областью памяти. Ниже приведен пример использования в коде BSD (, откуда берется функция, это вещь BSD ). Это, безусловно, то, что вы искали в Unices (, хотя он может быть доступен не во всех ОС Unix, таких как IRIX, HP -UX, AIX... вам нужно проверить ). Обратите внимание, что эта функция доступна всегда. Для его использования вам не нужна библиотека libhugetlbfs
. Обратите внимание, что под Linux не похоже, что они устанавливают что-то еще, кроме бита 0,это означает, что вы знаете только, является ли страница резидентной или нет, а не размер страницы, как в BSD.
Я практически исключительно работаю под Linux. Но для MS -Windows это называется «Большие страницы». У них есть документы здесь:https://docs.microsoft.com/en-us/windows/win32/memory/large-page-support
Наконец, различные реализации BSD называют эти «Супер-страницы» (macos, поэтому использует этот интерфейс ). Я нашел эту страницу с образцом кода, показывающим, сколько суперстраниц используется для большого malloc()
.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
int
main(int argc, char **argv)
{
size_t size, flags, i, super = 0, ordinary = 0;
void *addr;
char *vec;
if (argc != 2)
return (0);
size = atoi(argv[1]);
addr = malloc(size);
vec = malloc(size / 4096);
memset(addr, 0, size);
flags = mincore(addr, size, vec);
printf("addr %p len %d:\n", addr, size);
for (i = 0; i <= size / 4096; i++)
if (vec[i] & MINCORE_SUPER)
super++;
else
ordinary++;
printf("%d 4K blocks super-mapped, %d ordinary 4K pages\n",
super, ordinary);
return (0);
}
И некоторый вывод этого кода FreeBSD:
x23%./a.out 1000000
addr 0x801006000 len 1000000:
0 4K blocks super-mapped, 245 ordinary 4K pagesx23%./a.out 10000000
addr 0x801000000 len 10000000:
2048 4K blocks super-mapped, 394 ordinary 4K pagesx23%./a.out 100000000000
addr 0x801000000 len 1215752192:
296448 4K blocks super-mapped, 367 ordinary 4K pages
Как мы видим, первая цифра представляет «суперсопоставленные страницы», что означает, что она использует память, выделенную блоками по 2 Мб или 1 Гб или другими размерами в зависимости от вашей ОС и настроек, и она автоматически обрабатывается «под капотом».
ВАЖНО:Значение memset()
важно, оно фиксирует ВСЕ страницы выделенной памяти. Без этого вызова выделенные страницы могут быть 1 или 2...
Линукс
Разобрать содержимое /sys/kernel/mm/hugepages
(, что и делает libhugetlbfs
:
[~]# ls -l /sys/kernel/mm/hugepages/
total 0
drwxr-xr-x 2 root root 0 Dec 30 16:38 hugepages-1048576kB
drwxr-xr-x 2 root root 0 Dec 30 16:38 hugepages-2048kB
[~]#
В C (заголовки и проверка ошибок опущены для ясности):
// 16 should be plenty for this example (should really do this dynamically)
int size_count = 1;
// use unsigned long long to match strtoull()
unsigned long long page_sizes[ 16 ];
// get the base page size
page_sizes[ 0 ] = sysconf( _SC_PAGESIZE );
// now get the huge page size(s)
DIR *dirp = opendir( "/sys/kernel/mm/hugepages" );
for ( ;; )
{
struct dirent *dirent = readdir( dirp );
if ( NULL == dirent ) break;
if ( '.' == dirent->d_name[ 0 ] ) continue;
char *p = strchr( dirent->d_name, '-' );
if ( NULL == p ) continue;
page_sizes[ size_count++ ] = 1024ULL * strtoull( p + 1, NULL, 0 );
}
closedir( dirp );
Если у вас установлено libhugetlbfs-dev
:
#include <hugetlbfs.h>
int size_count = getpagesizes( NULL, 0 );
long page_sizes[ size_count ];
getpagesizes( page_sizes, size_count );
Связь с -lhugetlbfs
Солярис
В C используйте функцию getpagesizes()
:
#include <sys/mman.h>
int size_count = getpagesizes( NULL, 0 );
size_t page_sizes[ size_count ];
getpagesizes( page_sizes, size_count );
FreeBSD
FreeBSD скопировала функцию getpagesizes()
из Solaris 9:
#include <sys/mman.h>
int size_count = getpagesizes( NULL, 0 );
size_t page_sizes[ size_count ];
getpagesizes( page_sizes, size_count );