Michael IV
Michael IV

Reputation: 11424

boost::pool default number of chunks

I was trying to understand the strategy of boost::pool chunks pre-allocation.I read this and also this boost doc,but it is still not clear for me if it is possible to request a specific initial number of pre-allocated chunks when the pool is instantiated.When I say "chunk" I mean chunk = sizeof(SomeType) For example,I did this test:

Foo.h

  class Foo
  {
     public:
       typedef MAllocator<float>        FloatPoolAllocator;
       typedef std::shared_ptr<boost::pool<> >  FloatPoolSP;
       static FloatPoolSP                      _floatPoolSP;
       static FloatPoolAllocator               _floatAllocator;

       std::vector<float, FloatPoolAllocator> data1;

       std::vector<float, FloatPoolAllocator> data2;

       std::vector<float, FloatPoolAllocator> data3;

   };

Foo.cpp

    std::shared_ptr<boost::pool<> >   Foo::_floatPoolSP = std::shared_ptr<boost::pool<> >(new boost::pool<>(sizeof(uint8_t), 65536)); 

   MAllocator<float> Foo::_floatAllocator = MAllocator<float>(_floatPoolSP);

  Foo::Foo()
  {

    data1 = std::vector<float, FloatPoolAllocator>(_floatAllocator);
    data2 = std::vector<float, FloatPoolAllocator>(_floatAllocator);
    data3 = std::vector<float, FloatPoolAllocator>(_floatAllocator);

  }

Now,I am expecting my process memory to be at least twice the size of the specified boost::pool size because I allocate also other pools in different places with chunk sizes varying from 4 to 16 mb.This pool alone is 64 mb and looking into Windows Task Manager(not the best tool to investigate the memory...) I see the total memory consumption is around 78 mb.And it leads me to think that boost::pool doesn't allocate a block size of 65536,at least not at the first time.Is that true?And if it is,does it mean I need to wrap my own pool to allow such a functionality?Because I haven't found anything inside the pool that would allow another way of doing it.

PS: And if I remove the pools I see almost the same amount of memory used by the process which again probably means that boost::pool allocates a very small size of chunks.

Upvotes: 1

Views: 467

Answers (1)

Werner Erasmus
Werner Erasmus

Reputation: 4076

I was trying to understand the strategy of boost::pool chunks pre-allocation.I read this and also this boost doc,but it is still not clear for me if it is possible to request a specific initial number of pre-allocated chunks when the pool is instantiated.

No, it is not possible, except if you write your own allocator, which may keep some default.

The crux/essence of simple segregated storage is explained here (snipped from here):

Simple Segregated Storage is also extremely fast. In the simplest case, memory allocation is merely removing the first chunk from the free list, a O(1) operation. In the case where the free list is empty, another block may have to be acquired and partitioned, which would result in an amortized O(1) time. Memory deallocation may be as simple as adding that chunk to the front of the free list, a O(1) operation. However, more complicated uses of Simple Segregated Storage may require a sorted free list, which makes deallocation O(N).

From this you can see that boost pool allocates memory as required, when no free blocks exist (i.e. when the free list is empty). Therefore, possible no pre-allocation happens (or very little), but once something is allocated, freeing and reallocation is very fast (as essentially it is never really freed until the pool is out of scope).

Then I don't understand why they supply that "nextsize" param.Is it guaranteed at least that next block allocation will be equal to that size?

The allocators use make use of a singleton_pool instance of applicable tag type, depending on the allocator type. Singleton_pool instantiates an instance of pool, and from pools sources it can be seen that:

  • max_size is the maximum number of chunks to allocate to one block.
  • next_size is the number of chunks to request the first time that an object needs to allocate memory.
  • The other parameter (requested_size) is obtained from sizeof(T), the size of the requested object.

PS: And if I remove the pools I see almost the same amount of memory used by the process which again probably means that boost::pool allocates a very small size of chunks.

Yes, it uses the parameter next_size to allocate the first time, which may not be larger than max_size

Upvotes: 1

Related Questions