Как вы определяете размер узлов, созданных с помощью 'std :: map' для использования с 'boost :: pool_allocator' (кроссплатформенным способом)?
ОБНОВИТЬ
По комментариям, ответам и дополнительным исследованиям я пришел к выводу, что междуset
иmap
с точки зрения издержек узла. Мой следующий вопрос:
Как вы определяете издержки узла для удобного использованияboost::pool_allocator
как пользовательский распределитель?
И ещеОбновить: Возможно, служебная нагрузка на узел никогда не будет превышать 4 указателей, поэтому просто очистите Boost Pool дляsizeof(T)
, sizeof(T)+sizeof(int)
, sizeof(T) + 2*sizeof(int)
, sizeof(T) + 3*sizeof(int)
а такжеsizeof(T) + 4*sizeof(int)
(или жеint64_t
для 64-битных систем) должно быть хорошо. Это то, что я на самом деле делаю, и это работает.
Я хочу использоватьувеличить пул памяти управлять десятками миллионов крошечных объектов одинакового размера, избегая обращений к деструкторам этих объектов, и вместо этого освобождая память в отдельных областях, содержащих множество экземпляров на одну серию.
Я отправилДругой вопрос об этой проблеме, и ответ на этот вопрос привел меня к пониманию, что вопрос, который ядействительно нужно ответить, это то, что я спрашиваю здесь.
Рассмотрим следующий код:
class Obj { // ... has an operator<() ... };
typedef std::set<Obj, std::less<Obj>, boost::fast_pool_allocator<Obj>> fast_set_obj;
// Deliberately do not use a managed pointer -
// I will *NOT* delete this object, but instead
// I will manage the memory using the memory pool!!!
fast_set_obj * mset = new fast_set_obj;
// ... add some Obj's to 'mset'
mset->insert(Obj());
mset->insert(Obj());
// Do something desireable with the set ...
...
// All done.
// It's time to release the memory, but do NOT call any Obj destructors.
// The following line of code works exactly as intended.
boost::singleton_pool<boost::fast_pool_allocator_tag, sizeof(Obj const)>::purge_memory();
Если вы вступите вpurge_memory()
Функция последней строки кода, вы увидите, чтоfast_pool_allocator
приятно приступает к освобождению памяти из системы, просто как хотелось. (НетObj
деструкторы вызваны, потому что, как отмечено в связанном вопросе выше, работа пользовательского распределителяпросто выделить и освободить память,не вызывать конструкторов или деструкторов.)
Работает именно так, как хотелось бы. Большой!
Однако здесь есть проблема. Если вы заменитеset
сmap
, а затем попробуйте использоватьboost::pool_allocator
, Ничего не произошло в призыве кpurge_memory()
!
typedef std::map<int, int, std::less<int>,
boost::fast_pool_allocator<std::pair<int const, int>>>
fast_map_obj;
// Ditto above: Deliberately do not use managed pointer
mast_map_obj * mmap = new fast_map_obj;
mmap[5] = Obj();
mmap[6] = Obj();
...
// Uh-oh. The following line of code DOES NOTHING, because I was using a map, not a set!
boost::singleton_pool<boost::fast_pool_allocator_tag,
sizeof(std::pair<int const, int>)>::purge_memory();
Как уже отмечалось, последняя строка коданичего не делает, Причина в том, чтоboost::fast_pool_allocator
является единственным, который отвечает только на объекты и управляет памятью для объектовзаданного размера, который фиксируется во время компиляции, Вот почемуsizeof
Аргумент используется в выражении, которое вызываетpurge_memory()
- он сообщает код Boost Poolкоторый из различныхразные пула одноэлементной памяти для очистки (при условии, что запрошенный существует из-за того, что ранее был создан экземпляр).
К сожалению, поскольку пул памяти, выбранный для очистки, зависит от размера, онкритический что размер управляемых внутренних объектов (т.е. созданных и уничтоженных в памяти, выделенной посредством обращений к пользовательскому распределителю) известен. К сожалению, дляstd::map
размер внутренних объектов, управляемыхmap
не является ниsizeof(Obj)
ниsizeof(std::pair<int const, Obj>)
.
У меня вопрос: как вы строго и кроссплатформенным образом, который работает в соответствии со стандартом C ++ 11, определяете размер объектов, которыми внутренне управляетstd::map
для использования сboost::fast_pool_allocator
?
Это вообще возможно?