Topic: questions regarding N2387
Author: Lance Diduck <lancediduck@nyc.rr.com>
Date: Tue, 16 Oct 2007 18:21:48 CST Raw View
First I appreciate the wording in N2387 that changes the language of
20.1.2/4 concerning the typedefs. This wording makes it nearly
impossible to use a container in a place that otherwise could easily
be used, for instance to place a list or a vector in memory that is
relocatable (such as the memory you get when using mmap). I would love
to be able to portably typedef to something like Ion Gaztanga's
offset_ptr.
N2387 proposes to make "polymorphic allocators" the default. While not
required by the current standard, virtually every implementation of
the standard library containers can already make use of polymorphic
allocators *as an option.*. Indeed, it is fairly straightforward to
write adapters --using the current technology-- that makes containers
"allocator aware" in the manner described in the paper. I have done it
for the sequence containers, for example.
A question is: "Why not just an adapter, instead of a complete
reworking of existing containers?"
N2387 mentions tests that were done at Bloomberg LP. I was part of
those tests, and we found considerable issues with correctness --
especially when you actually cared just which allocator instance your
container happened to use. This is usually the case when you decide to
use something other than the default. However the semantic in N2387 is
"I prefer a particular allocator, but some other would do as well." In
fact, most Bloomberg developers preferred using the static allocators
to solve their problems, because there was no easy way to debug
problems with your container using the wrong allocator.
A question is: "What changes are also being considered that alleviate
some of the correctness issues?" (To alleviate some of these,
restrictions would also have to be place on many of the algorithms and
on RVO)
N2387 mentions that virtual dispatch does not add much in the way of
allocator overhead for the use cases tested at Bloomberg. But it is
not hard to find a use case where this mechanism overhead hits the
radar. The problem is not so much that the virtual dispatch itself
makes a dent: The problem is that with the semantics proposed in
N2387, you must always use allocators that can allocate any type of
object (or at least allocate any size). This is in essence the intent
of "polymorphic" and a requirement if your allocator is going to be
propagated from one container to another.
With typed allocators, it is common practice to write constant time
allocate/deallocate algorithms. It is also a common observation --even
outside the C++ community -- that it is more likely that object of the
same type are grouped together that objects of different types. Even
the Linux kernel makes this optimization. Indeed, in C++ the allocator
is always part of the type - that is what class specific operator new
is for. But when my allocator is allowed to freely propagated from one
container to another regardless of type, --becomes untyped-- this
optimization is difficult indeed. I suppose one could contrive a use
case where you would suffer locality of reference degradation for
heterogeneous objects that is solved by an allocator that groups these
objects on the same page. I have never heard of such a case in the
wild. In fact, in these cases the common practice is just to place
everything together in a struct that does not have members that
allocate anything, or use intrusive constructs.
A question: "Just what uses cases have you tried? Just what problem is
being solved, other than proving that it is possible to build
containers that propagate allocators?"
I make considerable use of polymorphic allocators in standard
containers. There are good reasons for using them. I have used them on
compilers ranging from gcc, MSVC6/7/8, Sun WS6U1/6U2, IBM aCC, and HP.
I have never had to use anything other than the native STL (although
working around some of the old member template oddities were a
challenge).
But to use polymorphic allocators correctly and effectively, the LAST
thing I want is my allocator automagically propagating from one
container to another, and I certainly don't want a default.
Lance
---
[ 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.comeaucomputing.com/csc/faq.html ]