Topic: Custom allocator for vector


Author: technews@kangaroologic.com ("Jonathan Turkanis")
Date: Thu, 26 Aug 2004 06:54:59 GMT
Raw View
"tom_usenet" <tom_usenet@hotmail.com> wrote:
> On Tue, 10 Aug 2004 17:18:53 GMT, alexvn@big-foot.com ("Alex
Vinokur")

> >The more specific question: do we need construct() and destroy()
indeed? For instance, g++ doesn't use them.
>
> We do need them for special pointer types, yes. e.g. a pointer might
> be an int (for an offset), in which case new((void*)anint) T(val) is
> just not going to work; the allocator will need something like:
>
> void myallocator::construct(pointer p, const_reference value)
> {
>   T* ptr = base_address + p;
>   new ((void*)ptr) value_type(value);
> }

How does this work if you've used allocate() to allocate memory for an
array of T?

Jonathan


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Fri, 27 Aug 2004 02:24:12 GMT
Raw View
tom_usenet wrote:
>
> We do need them for special pointer types, yes. e.g. a pointer might
> be an int (for an offset), in which case new((void*)anint) T(val) is
> just not going to work; the allocator will need something like:
>

According to my interpretation of tables 31, X::pointer cannot be int.
In particular, if p is a value of type X::pointer, the expression "*p"
need to be well-formed and be of type X::reference, a requirement that
cannot be fulfilled by an integral type.

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: do-not-spam-benh@bwsint.com (Ben Hutchings)
Date: Thu, 26 Aug 2004 00:05:26 GMT
Raw View
tom_usenet wrote:
> On Tue, 10 Aug 2004 17:18:53 GMT, alexvn@big-foot.com ("Alex Vinokur")
> wrote:
>
>>Different compilers produce quite different behavior with the same
>>custom allocator.
>>
>>Here is the Nicolai M. Josuttis' allocator code sample (for vector)
>>with cosmetic changes added by me to profile the executable:
>>http://groups.google.com/groups?threadm=2nrba8F3sq7sU1%40uni-berlin.de
>>
>>Here are run log files for the following compilers
>>* GNU g++ : http://groups.google.com/groups?selm=2nrb31F3q19kU1%40uni-berlin.de
>>* Microsoft C++ : http://groups.google.com/groups?selm=2nrbdaF3orecU1%40uni-berlin.de
>>* Borland C++ : http://groups.google.com/groups?selm=2nrbe9F3ta94U1%40uni-berlin.de
>>
>>We can see that
>>* GNU g++ 3.3.1 doesn't invoke construct() and destroy();
>>* Microsoft C++ 13.00 and Borland C++ 5.5.1 do invoke construct()
>>  and destroy().
>
> Unless your allocator is using a special type of pointer, I don't
> think an allocator should care whether construct() and destroy() are
> called or not, since the effects of those functions must be just to do
> a placement new and explicit destructor call.
>
> For example, an obvious optimization for POD types is not to call the
> destroy function at all.
<snip>

Consider an allocator for a (conservatively) garbage-collected heap.
When an object is destroyed but its memory is not deleted, any memory
that was referenced solely by it should not be considered reachable.
Therefore the object's memory should be cleared after its destructor
runs.  This can be done by the allocator's destroy() function,
dependent on the container invoking that function.

(Unfortunately I don't see a way for an allocator to tell whether or
not the object is going to be deleted after being destroyed, so there
is a trade-off between wasting memory by not clearing those pointers
and wasting time by clearing memory that's about to be freed.)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tom_usenet@hotmail.com (tom_usenet)
Date: Wed, 18 Aug 2004 05:34:36 GMT
Raw View
On Tue, 10 Aug 2004 17:18:53 GMT, alexvn@big-foot.com ("Alex Vinokur")
wrote:

>Different compilers produce quite different behavior with the same custom allocator.
>
>Here is the Nicolai M. Josuttis' allocator code sample (for vector) with cosmetic changes added by me to profile the executable:
>http://groups.google.com/groups?threadm=2nrba8F3sq7sU1%40uni-berlin.de
>
>Here are run log files for the following compilers
>* GNU g++ : http://groups.google.com/groups?selm=2nrb31F3q19kU1%40uni-berlin.de
>* Microsoft C++ : http://groups.google.com/groups?selm=2nrbdaF3orecU1%40uni-berlin.de
>* Borland C++ : http://groups.google.com/groups?selm=2nrbe9F3ta94U1%40uni-berlin.de
>
>We can see that
>* GNU g++ 3.3.1 doesn't invoke construct() and destroy();
>* Microsoft C++ 13.00 and Borland C++ 5.5.1 do invoke construct() and destroy().

Unless your allocator is using a special type of pointer, I don't
think an allocator should care whether construct() and destroy() are
called or not, since the effects of those functions must be just to do
a placement new and explicit destructor call.

For example, an obvious optimization for POD types is not to call the
destroy function at all.

>We can see also that behavior of Microsoft C++ 13.00 and Borland C++ 5.5.1 is quite different;
>for instance, Borland C++ allocates memory for 256 elements, Microsoft C++ allocates memory for small number of elements.

Yes, the minimum size of the vector is likely to be different
according to the choices made by different vendors. This is a good
thing; it has taken a long time for Dinkumware to settle on their
current allocation scheme, and there's no way the standard would have
got it right back in '96 or so.

However, it might be worth revisiting the container requirements in
C++0x, since so much more is known about them than was known when the
STL was a fresh new library. For example, more explicit control on how
deque and vector allocate memory might be useful.

>So, behavior of a custom allocator is significantly compiler-dependent.
>The question is what can one achieve using a _custom_ allocator?

You can allocate memory using a different technique than just using
::operator new. With better implementations like Dinkumware's (and
probably that of GCC 3.5), you can use custom pointer types (such as
an offset into shared memory).

>The more specific question: do we need construct() and destroy() indeed? For instance, g++ doesn't use them.

We do need them for special pointer types, yes. e.g. a pointer might
be an int (for an offset), in which case new((void*)anint) T(val) is
just not going to work; the allocator will need something like:

void myallocator::construct(pointer p, const_reference value)
{
  T* ptr = base_address + p;
  new ((void*)ptr) value_type(value);
}

Tom

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: alexvn@big-foot.com ("Alex Vinokur")
Date: Mon, 16 Aug 2004 16:42:41 GMT
Raw View
"Alex Vinokur" <alexvn@big-foot.com> wrote in message
http://groups.google.com/groups?selm=2ns6efF45gptU1%40uni-berlin.de

[snip]
> Here is the Nicolai M. Josuttis' code sample with cosmetic changes added by me to profile the executable:
> http://groups.google.com/groups?threadm=2nrba8F3sq7sU1%40uni-berlin.de
>
> Here are log files for the following compilers
> * GNU g++ : http://groups.google.com/groups?selm=2nrb31F3q19kU1%40uni-berlin.de
[snip]
>
> We can see that
> * GNU g++ 3.3.1 doesn't invoke construct() and destroy();
[snip]


"Matt Austern" <austern@apple.com> wrote in message
http://article.gmane.org/gmane.comp.gcc.libstdc++.devel/9815

> On Jul 19, 2004, at 9:25 AM, pippadav@dei.unipd.it wrote:
>
> > Hi everybody !
> >
> > There's a behaviour in STL allocator I don't understand, I hope
> > somebody can
> > help me...
> >
> > I'm trying to customize an allocator to track the insertion/deletion
> > of objects
> > in a container,
> > decorating the standard allocator functions construct() and destroy().
> >
> > The problem is that it seems that those functions are never called in
> > STL
> > containers, instead
> > a global template function _Construct() (defined in <stl_construct.h>)
> > is
> > called, that is
> > completely unaware of allocators.
>
> This is a bug.
[snip]

See also several relevant threads from news://news.gmane.org/gmane.comp.gcc.libstdc++.devel

The thread titled "Custom allocator for vector and libstdc++-v3"
http://thread.gmane.org/gmane.comp.gcc.libstdc++.devel/10087

The thread titled "allocator construct() / destruct() behaviour..."
http://thread.gmane.org/gmane.comp.gcc.libstdc++.devel/9814

The thread titled "PATCH: use construct and destroy from user-provided allocators"
http://thread.gmane.org/gmane.comp.gcc.libstdc++.devel/9847


--
   Alex Vinokur
     http://mathforum.org/library/view/10978.html
     http://sourceforge.net/users/alexvn




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: alexvn@big-foot.com ("Alex Vinokur")
Date: Tue, 10 Aug 2004 17:18:53 GMT
Raw View
Different compilers produce quite different behavior with the same custom allocator.

Here is the Nicolai M. Josuttis' allocator code sample (for vector) with cosmetic changes added by me to profile the executable:
http://groups.google.com/groups?threadm=2nrba8F3sq7sU1%40uni-berlin.de

Here are run log files for the following compilers
* GNU g++ : http://groups.google.com/groups?selm=2nrb31F3q19kU1%40uni-berlin.de
* Microsoft C++ : http://groups.google.com/groups?selm=2nrbdaF3orecU1%40uni-berlin.de
* Borland C++ : http://groups.google.com/groups?selm=2nrbe9F3ta94U1%40uni-berlin.de

We can see that
* GNU g++ 3.3.1 doesn't invoke construct() and destroy();
* Microsoft C++ 13.00 and Borland C++ 5.5.1 do invoke construct() and destroy().

We can see also that behavior of Microsoft C++ 13.00 and Borland C++ 5.5.1 is quite different;
for instance, Borland C++ allocates memory for 256 elements, Microsoft C++ allocates memory for small number of elements.


So, behavior of a custom allocator is significantly compiler-dependent.
The question is what can one achieve using a _custom_ allocator?

The more specific question: do we need construct() and destroy() indeed? For instance, g++ doesn't use them.


--
   Alex Vinokur
     http://mathforum.org/library/view/10978.html
     http://sourceforge.net/users/alexvn





---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]