Boost logo

Boost Users :

Subject: Re: [Boost-users] Zero-malloc memory pool for Boost Intrusive smart pointers
From: Francesco (francesco.montorsi_at_[hidden])
Date: 2019-03-22 20:25:59


Hi Gavin,

Il giorno ven 22 mar 2019 alle ore 05:44 Gavin Lambert via Boost-users <
boost-users_at_[hidden]> ha scritto:

> Did you look at std::make_shared<T>? It avoids the double allocation
> for the control block that you're complaining about. (Although you
> couldn't use it to allocate an arena block in this case -- while it does
> support array allocation, there is then only one control block for the
> whole array.)
>

Yes I know about std::make_shared<> and indeed I was using that solution
before implementing the memory pool based on intrusive pointers.
The problem is that in my workload I have several threads that need to get
a smart pointer to a fairly-big object every time they process input data
and they will release it later.
Now allocating with std::make_shared<> a new object on every input data
was causing my threads to do lots of mallocs/sec and that became the
performace limiting factor.
The use of a memory pool instead allows me to do a very large memory
allocation from time to time (in blocks of e.g. 1024 items) and still have
each single item of the memory pool independently refcounted.

This usage pattern is not possible with std::shared_ptr<> and that's why I
switched to boost::intrusive_ptr<> instead.

> Also the use of default construction and explicit recycle methods (and
> requiring boost_intrusive_pool_item as a base class) is ugly.

> You should be able to instead keep your pool_item type internal (not
> exposed to the consumer) and use aligned_storage to hold uninitialised
> storage for the actual item data, calling T's constructor and destructor
> as needed to allocate and recycle the slot.

My first implementation of the memory pool indeed was using C++11 perfect
forwarding to call the ctor/dtor of type T when the item was pulled out the
pool or was returning to it.
I later removed such feature because I realized that calling the ctor of
the items to recycle produced issues with classes having multiple
inheritance IIRC.
I don't think it's safe and sane to call the ctor of the same instance
multiple times...

I know that the implementation may be possibly refined from a C++/template
style point of view but regarding performances I verified that it satifies
well my needs and allows to write code using smart pointers that has
zero-malloc when the memory pool has expanded to contain enough elements to
handle the worst-simultaneous-active items...

(Or just wrap it in
> std/boost::optional, although that can introduce some nesting ambiguities.)
>

This is not very clear to me... but I will take a look at std::optional.

Thanks for the suggestions though!

Francesco



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net