std.allocator needs your help
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Sun Sep 22 19:28:42 PDT 2013
On 9/22/13 6:35 PM, Manu wrote:
> Well it looks like a good start, but the thing I'm left wondering after
> reading this is still... how is it actually used?
> I think the greatest challenge is finding a simple, clean
Oxford comma please :o)
> and correct
> way to actually specify which allocator should be used for making
> allocations throughout your code, and perhaps more troublesome; within
> generic code, and then layers of generic code.
My design makes it very easy to experiment by allowing one to define
complex allocators out of a few simple building blocks. It is not a
general-purpose allocator, but it allows one to define any number of such.
> Are you intending to be able to associate a particular allocator with a
> class declaration?
No, or at least not at this level.
> What about a struct declaration?
Same answer.
> What about a region of code (ie, a call tree/branch).
> What if the given allocator should be used for most of the tree, except
> for a couple of things beneath that always want to use their explicit
> allocator?
The proposed design makes it easy to create allocator objects. How they
are used and combined is left to the application.
> What if I want to associate an allocator instance, not just an allocator
> type (ie, I don't want multiple instances of the same type(/s) of
> allocators in my code, how are they shared?
An allocator instance is a variable like any other. So you use the
classic techniques (shared globals, thread-local globals, passing around
as parameter) for using the same allocator object from multiple places.
> It wasn't clear to me from your demonstration, but 'collect()' implies
> that GC becomes allocator-aware; how does that work?
No, each allocator has its own means of dealing with memory. One could
define a tracing allocator independent of the global GC.
> deallocateAll() and collect() may each free a whole lot of memory, but
> it seems to me that they may not actually be aware of the individual
> allocations they are freeing; how do the appropriate destructors for the
> sub-allocations get called?
No destructors are called at this level. Again, all these allocators
understand is ubyte[].
> I have a suspicion you're going to answer most of these questions with
> the concept of allocator layering, but I just don't completely see it.
No, it's just that at this level some of these questions don't even have
an appropriate answer - like we discuss atoms and molecules and you ask
about building floors and beams and pillars.
> It's quite an additional burden of resources and management to manage
> the individual allocations with a range allocator above what is supposed
> to be a performance critical allocator to begin with.
I don't understand this.
> C++'s design seems reasonable in some ways, but history has demonstrated
> that it's a total failure, which is almost never actually used (I've
> certainly never seen anyone use it).
Agreed. I've seen some uses of it that quite fall within the notion of
the proverbial exception that prove the rule.
> Some allocators that I use regularly to think about:
>
> A ring-buffer:
> * Like a region allocator I guess, but the circular nature adds some
> minor details, and requires the user to mark the heap from time to time,
> freeing all allocations between the old mark and the new mark.
>
> A pool:
> * Same as a free-list, but with a maximum size, ie, finite pool of
> objects pre-allocated and pre-populating the freelist.
I implemented the finite size for a freelist.
> A pool-group:
> * Allocate from a group of pools allocating differently sized
> objects. (this is a good test for allocator layering, supporting a group
> of pools above, and fallback to the malloc heap for large objects)
I implemented that as well, it's one of the best designs I've defined in
my life.
Andrei
More information about the Digitalmars-d
mailing list