Я вижу на http://msdn.microsoft.com/en-us/library/ee292117.aspx а также http://msdn.microsoft.com/en-us/library/ee292134.aspx что Microsoft предоставляет макросы и классы для специализированных распределителей, но я не уверен, какова каждая из стратегий кэширования, как их использовать. Может кто-нибудь объяснить, когда использовать каждую из этих частей?
cache_freelist
— cache_freelist
Шаблон класса поддерживает свободный список блоков памяти размера Sz
, Когда свободный список заполнен, он использует operator delete
освободить блоки памяти. Когда свободный список пуст, он использует operator new
выделить новые блоки памяти. Максимальный размер свободного списка определяется классом max class
прошло в Max
параметр. Каждый блок памяти содержит Sz
байт используемой памяти и данных, которые operator new
а также operator delete
требуют.cache_suballoc
— cache_suballoc
класс шаблона хранит освобожденные блоки памяти в свободном списке неограниченной длины, используя freelist<sizeof(Type), max_unbounded>
и выделяет блоки памяти из большего блока, выделенного с помощью operator new
когда свободный список пуст. Каждый кусок держит Sz * Nelts
байт используемой памяти и данных, которые operator new
а также operator delete
требуют. Выделенные куски никогда не освобождаются.cache_chunklist
— Этот класс шаблона использует operator new
выделять куски сырой памяти, распределять блоки для выделения памяти для блока памяти, когда это необходимо; он хранит освобожденные блоки памяти в отдельном свободном списке для каждого чанка и использует operator delete
освободить блок, когда ни один из его блоков памяти не используется. Каждый блок памяти содержит Sz
байты используемой памяти и указатель на блок, которому он принадлежит. Каждый кусок держит Nelts
блоки памяти, три указателя, int и данные, которые operator new
а также operator delete
требуют.Я сам написал несколько распределителей, но эта документация просто … сбивает с толку.
Вау, они действительно исказили документацию, не так ли? (Я написал этот код, когда был в Dinkumware)
Распределители здесь основаны на политике: вы можете указать политику кэширования и политику синхронизации.
Основная идея состоит в том, чтобы упростить написание распределителей, которые используют внутренние кэши и могут быть синхронизированы между потоками. Есть полдюжины предопределенных распределителей; их имена начинаются с allocator_
, Используйте их, если они соответствуют вашим потребностям. В материале MSDN посмотрите на первый абзац описания конкретного распределителя; не читайте «Замечания», где они говорят о ALLOCATOR_DECL
;.
Вы также можете использовать этот код для создания собственных распределителей, которые используют предопределенные стратегии кэширования (шаблоны, имена которых начинаются с cache_
) и стратегии синхронизации (шаблоны, названия которых начинаются с sync_
) или использовать свой собственный шаблон кэширования и шаблон синхронизации. Получить полезный распределитель из этих частей немного утомительно, поэтому заголовок обеспечивает ALLOCATOR_DECL
как удобный способ произвести все необходимые шаблоны без необходимости писать их самостоятельно. ALLOCATOR_DECL
принимает три аргумента: имя используемого шаблона кэша, имя используемого шаблона синхронизации и имя создаваемого распределителя. Так что вместо того, чтобы писать
template <class T> class name
: public Dinkum::allocators::allocator_base<T, sync<cache > >
{
public:
name() {}
template <class U> name(const name<U>&) {}
template <class U> name& operator = (const name<U>&)
{return *this; }
template <class U> struct rebind
{ /* convert a name<T> to a name<U> */
typedef name<U> other;
};
};
ты бы написал ALLOCATOR_DECL(cache, sync, name);
, allocator_base
выполняет тяжелую работу; сам распределитель должен быть производным типом, чтобы он мог обрабатывать rebind
правильно. (The Dinkum
в этом коде взято из документации Dinkumware; Я не знаю, в какое пространство имен Microsoft помещает эти имена, но, вероятно, макрос помещает туда правильное имя).
Для шаблонов кеша:
cache_freelist
поддерживает связанный список блоков размером с узел; максимальный размер списка задается параметром шаблона Sz
и распределение узлов управляется с помощью operator new
а также operator delete
, cache_suballoc
добавляет еще один слой, который управляет блоком Nelts
блоки узлов, все выделенные как один большой двоичный объект; При выделении нового элемента сначала выполняется поиск в свободном списке, а если нет ничего свободного, выделяется новый BLOB-объект. Блоки памяти не удаляются, пока не будет уничтожен распределитель. cache_chunklist
выделяет память в каплях (например, cache_suballoc
), но не использует общий свободный список; когда блок освобождается, он возвращается в список свободных для своего блоба. Когда все блоки BLOB-объектов были освобождены, сам BLOB-объект удаляется.Первый вопрос легко. Когда их использовать? При профилировании отображается проблема с распределителем по умолчанию. Уже одно это делает вопрос неуместным для большинства разработчиков.
В некоторых макросах используется глагол «доходность», что в широком смысле означает «в конечном итоге расширяется, возможно, за несколько шагов».
Шаблоны кэша сохраняют освобожденные блоки для последующего перераспределения. Вы бы выбрали кеш, который лучше всего подходит для вашего шаблона размещения, тот, который имеет лучший компромисс между повторным использованием% и размером кеша (см. Профилирование выше).
Некоторые шаблоны кеша имеют конечное количество освобожденных блоков, реализованных через freelist<>
, Классы Max определяют, как долго freelist
может стать.
Распределители, наконец, представляют собой заранее составленные комбинации вышеперечисленного.