<div dir="ltr">On 23 September 2013 12:28, Andrei Alexandrescu <span dir="ltr"><<a href="mailto:SeeWebsiteForEmail@erdani.org" target="_blank">SeeWebsiteForEmail@erdani.org</a>></span> wrote:<br><div class="gmail_extra">
<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">On 9/22/13 6:35 PM, Manu wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Well it looks like a good start, but the thing I'm left wondering after<br>
reading this is still... how is it actually used?<br>
I think the greatest challenge is finding a simple, clean<br>
</blockquote>
<br></div>
Oxford comma please :o)<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
and correct<br>
way to actually specify which allocator should be used for making<br>
allocations throughout your code, and perhaps more troublesome; within<br>
generic code, and then layers of generic code.<br>
</blockquote>
<br></div>
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.</blockquote>
<div><br></div><div>Oh okay, so this isn't really intended as a system then, so much a suggested API?</div><div>That makes almost all my questions redundant. I'm interested in the system, not the API of a single allocator (although your API looks fine to me).</div>
<div>I already have allocators I use in my own code. Naturally, they don't inter-operate with anything, and that's what I thought std.allocator was meant to address.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Are you intending to be able to associate a particular allocator with a<br>
class declaration?<br>
</blockquote>
<br></div>
No, or at least not at this level.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
What about a struct declaration?<br>
</blockquote>
<br></div>
Same answer.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
What about a region of code (ie, a call tree/branch).<br>
What if the given allocator should be used for most of the tree, except<br>
for a couple of things beneath that always want to use their explicit<br>
allocator?<br>
</blockquote>
<br></div>
The proposed design makes it easy to create allocator objects. How they are used and combined is left to the application.</blockquote><div><br></div><div>Is that the intended limit of std.allocator's responsibility, or will patterns come later?</div>
<div><br></div><div>Leaving the usage up to the application means we've gained nothing.</div><div>I already have more than enough allocators which I use throughout my code. The problem is that they don't inter-operate, and certainly not with foreign code/libraries.</div>
<div>This is what I hoped std.allocator would address.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
What if I want to associate an allocator instance, not just an allocator<br>
type (ie, I don't want multiple instances of the same type(/s) of<br>
allocators in my code, how are they shared?<br>
</blockquote>
<br></div>
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.</blockquote>
<div><br></div><div>Okay, that's fine... but this sort of manual management implies that I'm using it explicitly. That's where it all falls down for me.</div><div><br></div><div><div>Eg, I want to use a library, it's allocation patterns are incompatible with my application; I need to provide it with an allocator.</div>
<div>What now? Is every library responsible for presenting the user with a mechanism for providing allocators? What if the author forgets? (a problem I've frequently had to chase up in the past when dealing with 3rd party libraries)</div>
<div><br></div><div>Once a library is designed to expect a user to supply an allocator, what happens if the user doesn't? Fall-back logic/boilerplate exists in every library I guess...</div><div>And does that mean that applications+libraries are required to ALWAYS allocate through given allocator objects?<br>
</div><div>That effectively makes the new keyword redundant. And what about the GC?</div></div><div><br></div><div>I can't really consider std.allocator intil it presents some usage patterns.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
It wasn't clear to me from your demonstration, but 'collect()' implies<br>
that GC becomes allocator-aware; how does that work?<br>
</blockquote>
<br></div>
No, each allocator has its own means of dealing with memory. One could define a tracing allocator independent of the global GC.</blockquote><div><br></div><div>I'm not sure what this means. Other than I gather that the GC and allocators are fundamentally separate?</div>
<div>Is it possible to create a tracing allocator without language support? Does the current language insert any runtime calls to support the GC?</div><div><br></div><div>I want a ref-counting GC for instance to replace the existing GC, but it's impossible to implement one of them nicely without support from the language, to insert implicit inc/dec ref calls all over the place, and to optimise away redundant inc/dec sequences.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
deallocateAll() and collect() may each free a whole lot of memory, but<br>
it seems to me that they may not actually be aware of the individual<br>
allocations they are freeing; how do the appropriate destructors for the<br>
sub-allocations get called?<br>
</blockquote>
<br></div>
No destructors are called at this level. Again, all these allocators understand is ubyte[].</blockquote><div><br></div><div>Fair enough. That's a problem for another time then.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I have a suspicion you're going to answer most of these questions with<br>
the concept of allocator layering, but I just don't completely see it.<br>
</blockquote>
<br></div>
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.</blockquote><div><br></div>
<div>Yep, fair enough.</div><div>I just saw "<span style="font-family:arial,sans-serif;font-size:13px">I am making good progress on the design of std.allocator" and presumed you had some thoughts about actual usage semantics of the system.</span></div>
<div><span style="font-family:arial,sans-serif;font-size:13px">I can easily define an allocator to use in my own code if it's entirely up to me how I use it, but that completely defeats the purpose of this exercise.</span></div>
<div><span style="font-family:arial,sans-serif;font-size:13px">Until there aren't standard usage patterns, practises, conventions that ALL code follows, then we have nothing. I was hoping to hear your thoughts about those details.</span></div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
It's quite an additional burden of resources and management to manage<br>
the individual allocations with a range allocator above what is supposed<br>
to be a performance critical allocator to begin with.<br>
</blockquote>
<br></div>
I don't understand this.</blockquote><div><br></div><div>It's irrelevant here.</div><div>But fwiw, in relation to the prior point about block-freeing a range allocation; there will be many *typed* allocations within these ranges, but a typical range allocator doesn't keep track of the allocations within.<br>
</div><div>This seems like a common problem that may or may not want to be addressed in std.allocator.</div><div>If the answer is simply "your range allocator should keep track of the offsets of allocations, and their types", then fine. But that seems like boilerplate that could be automated, or maybe there is a different/separate system for such tracking?</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
C++'s design seems reasonable in some ways, but history has demonstrated<br>
that it's a total failure, which is almost never actually used (I've<br>
certainly never seen anyone use it).<br>
</blockquote>
<br></div>
Agreed. I've seen some uses of it that quite fall within the notion of the proverbial exception that prove the rule.</blockquote><div><br></div><div>I think the main fail of C++'s design is that it mangles the type.</div>
<div>I don't think a type should be defined by the way it's memory is allocated, especially since that could change from application to application, or even call to call. For my money, that's the fundamental flaw in C++'s design.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Some allocators that I use regularly to think about:<br>
<br>
A ring-buffer:<br>
   * Like a region allocator I guess, but the circular nature adds some<br>
minor details, and requires the user to mark the heap from time to time,<br>
freeing all allocations between the old mark and the new mark.<br>
<br>
A pool:<br>
   * Same as a free-list, but with a maximum size, ie, finite pool of<br>
objects pre-allocated and pre-populating the freelist.<br>
</blockquote>
<br></div>
I implemented the finite size for a freelist.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
A pool-group:<br>
   * Allocate from a group of pools allocating differently sized<br>
objects. (this is a good test for allocator layering, supporting a group<br>
of pools above, and fallback to the malloc heap for large objects)<br>
</blockquote>
<br></div>
I implemented that as well, it's one of the best designs I've defined in my life.</blockquote><div><br></div><div>Well as an atom, as you say, it seems like a good first step.</div><div>I can't see any obvious issues, although I don't think I quite understand the collect() function if it has no relation to the GC. What is it's purpose?</div>
<div>If the idea is that you might implement some sort of tracking heap which is able to perform a collect, how is that actually practical without language support?</div><div><br></div><div>I had imagined going into this that, like the range interface which the _language_ understands and interacts with, the allocator interface would be the same, ie, the language would understand this API and integrate it with 'new', and the GC... somehow.</div>
<div>If allocators are just an object like in C++ that people may or may not use, I don't think it'll succeed as a system. I reckon it needs deep language integration to be truly useful.</div><div><br></div><div>The key problem to solve is the friction between different libraries, and different moments within a single application its self.</div>
<div>I feel almost like the 'current' allocator needs to be managed as some sort of state-machine. Passing them manually down the callstack is no good. And 'hard' binding objects to their allocators like C++ is no good either.</div>
</div></div></div>