The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа

Memory Slices

Memory Slices — Эффективный способ распределения групп эквивалентных по размеру участков памяти.

Краткое описание


#include <glib.h>


gpointer    g_slice_alloc                   (gsize block_size);
gpointer    g_slice_alloc0                  (gsize block_size);
void        g_slice_free1                   (gsize block_size,
                                             gpointer mem_block);
void        g_slice_free_chain_with_offset  (gsize block_size,
                                             gpointer mem_chain,
                                             gsize next_offset);

#define     g_slice_new                     (type)
#define     g_slice_new0                    (type)
#define     g_slice_free                    (type, mem)
#define     g_slice_free_chain              (type, mem_chain, next)

Описание

Слайсы памяти обеспечивают пространственно-эффективный и многопроцессорно-масштабируемый путь для распределения равных по размеру частей памяти, так же как оригинальный GMemChunks (from GLib <= 2.8), избегая чрезмерной траты памяти, потери масштабируемости и проблем выполнения.

Для достижения этих целей, распределитель слайсов использует сложный, многоуровневый дизайн который был создан благодаря распределителю слайсов Bonwick's [5]. Он использует posix_memalign() для оптимизированного распределения множества участков одинакового размера и имеет посредством потока свободные списки (так называемый уровень журналирования) для быстрого удовлетворения запросов распределения уже известных размеров структур. Это сопровождается дополнительным логическим кэшированием, чтобы иметь свободную память в течении некоторого времени перед возвращением в систему. Память которая не используется из-за ограничений выравнивания, используется для колоризации кэша (произвольное распределение адресов участка) для улучшенного использования кэша CPU. Кэширующий уровень распределителя слайсов самостоятельно адаптируется к высокой конкуренции блокирования для улучшения масштабируемости.

Распределитель слайсов может распределять небольшие блоки в два указателя, и в отличие от malloc(), он не резервирует дополнительное пространство в блоке. Для блоков большого размера, g_slice_new() и g_slice_alloc() автоматически делегируют к системной реализации malloc(). Для вновь создаваемого кода рекомендуется использовать новый g_slice API вместо g_malloc() и подобных, пока объекты не изменяют размер в течении их жизненного цикла и размер объекта используемый во время распределения остаётся доступным когда освобождается.

Пример 1. Использование распределителя слайсов

  gchar *mem[10000];
  gint i;

  /* Распределяем 10000 блоков. */
  for (i = 0; i < 10000; i++)
    {
      mem[i] = g_slice_alloc (50);

      /* Fill in the memory with some junk. */
      for (j = 0; j < 50; j++)
	mem[i][j] = i * j;
    }

  /* Освобождаем все блоки. */
  for (i = 0; i < 10000; i++)
    {
      g_slice_free1 (50, mem[i]);
    }

Пример 2. Использование распределителя слайсов со структурами данных

  GRealArray *array;

  /* Распределяем один блок, используя макрос g_slice_new(). */
  array = g_slice_new (GRealArray);

  /* Теперь мы можем использовать массив как обычный указатель на структуру. */
  array->data            = NULL;
  array->len             = 0;
  array->alloc           = 0;
  array->zero_terminated = (zero_terminated ? 1 : 0);
  array->clear           = (clear ? 1 : 0);
  array->elt_size        = elt_size;

  /* Мы можем освобождать блок, поэтому он может использоваться многократно. */
  g_slice_free (GRealArray, array);

Детали

g_slice_alloc ()

gpointer    g_slice_alloc                   (gsize block_size);

Распределяет блок памяти из распределителя слайсов. Адрес полученного блока, как гарантируется, будет выравнен по крайней мере 2 * sizeof (void*). Помните что основной механизм распределения слайсов может быть изменён с помощью переменной окружения G_SLICE=always-malloc.

block_size : количество байт для распределения
Возвращает : указатель на распределённую память block

Начиная с версии 2.10


g_slice_alloc0 ()

gpointer    g_slice_alloc0                  (gsize block_size);

Распределяет блок памяти через g_slice_alloc() и инициализирует возвращаемую память 0. Помните что основной механизм распределения слайсов может быть изменён с помощью переменной окружения G_SLICE=always-malloc.

block_size : количество байт для распределения
Возвращает : указатель на распределённый блок

Начиная с версии 2.10


g_slice_free1 ()

void        g_slice_free1                   (gsize block_size,
                                             gpointer mem_block);

Освобождает блок памяти. Память должна быть распределена через g_slice_alloc() или g_slice_alloc0(), а block_size должен соответствовать размеру определённому при распределении. Помните что существующее поведение может быть изменено с помощью переменной окружения G_DEBUG=gc-friendly.

block_size : размер блока
mem_block : указатель на блок для освобождения

Начиная с версии 2.10


g_slice_free_chain_with_offset ()

void        g_slice_free_chain_with_offset  (gsize block_size,
                                             gpointer mem_chain,
                                             gsize next_offset);

Освобождает связанный список блоков памяти структуры имеющей тип type. Блоки памяти должны быть одинакового размера, распределённые через g_slice_alloc() или g_slice_alloc0() и связаны вместе указателем next (также как в GSList). Смещение поля next передаётся в каждый блок как третий аргумент. Помните что существующее поведение может быть изменено с помощью переменной окружения G_DEBUG=gc-friendly.

block_size : размер блоков
mem_chain : указатель на первый блок в цепочке
next_offset : поле смещения next в блоках

Начиная с версии 2.10


g_slice_new()

#define     g_slice_new(type)

Удобный макрос для распределения блоков памяти из распределителя слайсов. Он вызывает g_slice_alloc() с sizeof (type) и приводит возвращаемый указатель к указателю данного типа, избегая приведения типа в исходном коде. Помните что основной механизм распределения слайсов может быть изменён с помощью переменной окружения G_SLICE=always-malloc.

type : тип для распределения, обычно имя структуры
Возвращает : указатель на распределённый блок, приведённый к указателю type.

Начиная с версии 2.10


g_slice_new0()

#define     g_slice_new0(type)

Удобный макрос для распределения блока памяти из распределителя слайсов и установки памяти в 0. Он вызывает g_slice_alloc0() с sizeof (type) и приводит возвращаемый указатель к указателю полученного типа, избегая приведения указателя в исходном коде. Помните что основной механизм распределения слайсов может быть изменён с помощью переменной окружения G_SLICE=always-malloc.

type : тип для распределения, обычно имя структуры
Возвращает : указатель на распределённый блок, приведённый к указателю type.

Начиная с версии 2.10


g_slice_free()

#define     g_slice_free(type, mem)

Удобный макрос для освобождения блока памяти который был распределён из распределителя слайсов. Он вызывает g_slice_free1() используя sizeof (type) как размер блока. Помните что существующее поведение может быть изменено с помощью переменной окружения G_DEBUG=gc-friendly.

type : тип блока для освобождения, обычно имя структуры
mem : указатель на блок для освобождения

Начиная с версии 2.10


g_slice_free_chain()

#define     g_slice_free_chain(type, mem_chain, next)

Освобождает связанный список блоков памяти структуры имеющей тип type. Блоки памяти должны быть одинакового размера, распределены через g_slice_alloc() или g_slice_alloc0() и связаны вместе указателем next (так же как в GSList). Имя поля next в type помещают как третий аргумент. Помните что существующее поведение может быть изменено с помощью переменной окружения G_DEBUG=gc-friendly.

type : тип mem_chain блоков
mem_chain : указатель на первый блок цепочки
next : имя поля следующего указателя в type

Начиная с версии 2.10



[5] [Bonwick94] Jeff Bonwick, The slab allocator: Кэширующий объекты распределитель памяти ядра. USENIX 1994, и [Bonwick01] Bonwick and Jonathan Adams, Magazines and vmem: Расширенное распределение слайсов для множества процессоров и произвольных ресурсов. USENIX 2001




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2021 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру