How do you determine the size of the nodes created by "std :: map" for use with "boost :: pool_allocator" (cross-platform way)?

UPDATE

In the comments, answers and additional research, I came to the conclusion that usually there is a difference between setand a mapin terms of node overhead. My next question is valid:

How do you define node overhead for convenient use boost::pool_allocatoras a custom allocator?

And another update : service data node, probably will never exceed the size of 4 pointers, so a clean Boost Pool for sizeof(T), sizeof(T)+sizeof(int), sizeof(T) + 2*sizeof(int), sizeof(T) + 3*sizeof(int)and sizeof(T) + 4*sizeof(int)(or int64_tfor 64-bit systems) must be accurate. This is what I actually do, and it works.


I want to use the increase memory pool to manage tens of millions of small objects of the same size, avoiding calls to destructors of these objects, and instead freeing up memory in single rows containing many instances per shaft.

I sent another question about this problem, and the answer to this question made me realize that the question I really have to answer is the one I ask here.

:

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 to 'mset'
mset->insert(Obj());
mset->insert(Obj());

// Do something desireable with the set ...
...

// All done.
// It 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>).

: - , ++ 11, , std::map boost::fast_pool_allocator?

?

+4
2

, , set .

, , , sizeof node allocate, :

template<typename T>
struct SimpleAllocator : private std::allocator<T>
{
    using value_type = T;
    using pointer = typename std::allocator<T>::pointer;
    using size_type = typename std::allocator<T>::size_type;

    pointer allocate(size_type n)
    {   
        std::cout << "Allocator sizeof(T)==" << sizeof(T) << '\n';
        return std::allocator<T>::allocate(n);
    }   

    void deallocate(pointer p, size_type n)
    { return std::allocator<T>::deallocate(p, n); }
};

( ints):

std::set<int, std::less<int>, SimpleAllocator<int>> s;
s.insert(2);

:

sizeof (T) == 32

+2

- - , , -, node, .

- , #ifdef -ed . , g++/clang++/msc std libs:

// libstdc++
boost::singleton_pool<boost::fast_pool_allocator_tag,
    sizeof(std::_Rb_tree_node<fast_map_obj::value_type>)>::purge_memory()

// libc++
boost::singleton_pool<boost::fast_pool_allocator_tag,
    sizeof(std::__tree_node<fast_map_obj::value_type, void*>)>::purge_memory()

// msvc 2013 (incl. nov ctp)
boost::singleton_pool<boost::fast_pool_allocator_tag,
    sizeof(fast_map_obj::_Node)>::purge_memory()

:

http://www.boost.org/doc/libs/1_55_0/boost/config/compiler/

http://sourceforge.net/p/predef/wiki/Compilers/

+2

Source: https://habr.com/ru/post/1535592/


All Articles