Большие метаданные выделения вызывают фрагментацию и неэффективную трату DRAM в jemalloc при использовании перехватчиковC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Большие метаданные выделения вызывают фрагментацию и неэффективную трату DRAM в jemalloc при использовании перехватчиков

Сообщение Anonymous »

Я пишу простой пользовательский распределитель экстентов, который возвращает экстенты из предварительно сопоставленной области (таким образом я могу явно контролировать сопоставленную область и выделения в ней). Я использую ветку разработки. Вот простой тестовый файл, в котором мы выполняем 100 выделений по 1024 байта (размер выделения не имеет значения) и устанавливаем собственный перехватчик выделения.

Код: Выделить всё

#include 
#include 
#include "/home/vin/jemalloc/include/jemalloc/jemalloc.h"
#include 
/*
To run this test:
1. clone jemalloc: git clone https://github.com/jemalloc/jemalloc.git
2. configure jemalloc with --with-jemalloc-prefix=jem_
3. build test:
g++ -std=c++17 -I/home/user/jemalloc/include -L/home/user/jemalloc/lib test.cc -o test -ljemalloc
*/
const size_t INITIAL_MMAP_SIZE = 1ULL * 1024 * 1024 * 1024; // 1 GiB

struct ArenaInfo
{
uintptr_t base_pointer;
uintptr_t pre_alloc;
} info;

void *extent_alloc_hook_dram(extent_hooks_t *extent_hooks, void *new_addr, size_t size,
size_t alignment, bool *zero, bool *commit, unsigned arena_ind)
{
uintptr_t ret = (info.pre_alloc + alignment - 1) & ~(alignment - 1);
if (ret + size > info.base_pointer + INITIAL_MMAP_SIZE)
return nullptr;
info.pre_alloc = ret + size;
if (*zero)
memset(reinterpret_cast(ret), 0, size);
printf(">>> extent request: size %lu ret %p alignment %lu\n", size, (void *)ret, alignment);
return reinterpret_cast(ret);
}

int main()
{
extent_hooks_t *hooks = new extent_hooks_s();
memset(hooks, 0, sizeof(extent_hooks_s));
hooks->alloc = extent_alloc_hook_dram;
info.base_pointer = reinterpret_cast(mmap(NULL, INITIAL_MMAP_SIZE,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
if (reinterpret_cast(info.base_pointer) == MAP_FAILED)
{
std::cerr  extent request: size 2097152 ret 0x7fffb7000000 alignment 4096
>>> extent request: size 4096 ret 0x7fffb7200000 alignment 4096
1024 0x7fffb7200000
1024 0x7fffb7200400
1024 0x7fffb7200800
1024 0x7fffb7200c00
>>> extent request: size 2097152 ret 0x7fffb7201000 alignment 4096
>>> extent request: size 4096 ret 0x7fffb7401000 alignment 4096
1024 0x7fffb7401000
1024 0x7fffb7401400
1024 0x7fffb7401800
1024 0x7fffb7401c00
>>> extent request: size 2097152 ret 0x7fffb7402000 alignment 4096
>>> extent request: size 4096 ret 0x7fffb7602000 alignment 4096
1024 0x7fffb7602000
1024 0x7fffb7602400
1024 0x7fffb7602800
1024 0x7fffb7602c00
>>> extent request: size 2097152 ret 0x7fffb7603000 alignment 4096
>>> extent request: size 4096 ret 0x7fffb7803000 alignment 4096
1024 0x7fffb7803000
1024 0x7fffb7803400
1024 0x7fffb7803800
1024 0x7fffb7803c00
jemalloc периодически запрашивает экстенты размером 2 МБ. После каждых 2 МБ экстента он запрашивает экстент размером 4 КБ.
Я ожидал, что все 1024 выделения (принадлежащие к одному и тому же классу размера) должны находиться в непрерывном блоке. После каждых 4 1024 выделений запрашивается экстент размером 2 МБ, который предположительно используется для метаданных, и, следовательно, для хранения наших выделений запрашивается экстент 4096 B. Итак, теперь вы можете видеть, как простое последовательное распределение (одного и того же класса размера) без всякой причины размещает выделения на расстоянии 2 МБ друг от друга. Я называю использование метаданных «высоким и расточительным», потому что нам не нужны 2 МБ экстента метаданных для управления одним экстентом размером 4 КиБ. В идеале я бы не ожидал запроса на экстенты размером 2 МБ до тех пор, пока не будет заполнено большое количество страниц.

Подробнее здесь: https://stackoverflow.com/questions/787 ... n-jemalloc
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»