Узнайте о поддержке огромных страниц в POSIX или Linux

Чтобы установить соответствующий linux-headersобраз ядра, получите доступный linux-headersчерез:

apt-cache search linux-headers

Затем установите:

apt-get install linux-headers-4.9.0-kali4-amd64
1
12.05.2017, 02:01
2 ответа

Для 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 pages

x23%./a.out 10000000
addr 0x801000000 len 10000000:
2048 4K blocks super-mapped, 394 ordinary 4K pages

x23%./a.out 100000000000
addr 0x801000000 len 1215752192:
296448 4K blocks super-mapped, 367 ordinary 4K pages

Как мы видим, первая цифра представляет «суперсопоставленные страницы», что означает, что она использует память, выделенную блоками по 2 Мб или 1 Гб или другими размерами в зависимости от вашей ОС и настроек, и она автоматически обрабатывается «под капотом».

ВАЖНО:Значение memset()важно, оно фиксирует ВСЕ страницы выделенной памяти. Без этого вызова выделенные страницы могут быть 1 или 2...

2
04.02.2020, 17:38

Линукс

Разобрать содержимое /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 );
0
30.12.2020, 21:27

Теги

Похожие вопросы