October 25, 2013
>> Because Array!int looks a lot more ugly than such a nice thing as int[].
>> And if it is possible to change the allocator for some arrays, why
>> shouldn't we implement it?
>> The default allocator would stay the GC allocator. So if you don't want
>> to swap the allocator of your arrays, don't do it.
>
> Maintaining per-array-object allocators could be quite expensive. Two other possibilities are keeping one allocators for all array of a given type and of course keeping a global allocator for all arrays.
>
> Andrei

Sounds also nice. As long as you can customize the way built-in arrays allocate, I'm fine with that. :)
October 25, 2013
On 10/25/13 5:50 AM, Timon Gehr wrote:
> - Possible null dereference on line 3128. :o)
>    (In general, CascadingAllocator is not yet very composable. It should
> return null allocations instead of failing in undocumented ways.

Good point. Fixed and pushed.

> It
> should probably also allow the 'make' function to return null.)

make() returns Allocator objects by value, not pointers.

> - "CAllocator". The name is non-descriptive/misleading.

"Class Allocator" :o)

> - Preconditions should be in the corresponding section.

Will do...


Andrei
October 25, 2013
On 10/25/13 7:23 AM, Manu wrote:
> My immediate reactions:
>
> 1. I'm still sad there are no allocAligned() functions or something of
> that type to request explicit alignment with allocations. I'm not sure
> there is sufficient support for requesting alignment with allocations.
> The set-able alignment property approach seems a little weird (and only
> seemed to be supported on one allocator?). I guess experience will tell
> if this is sufficient and/or convenient.
> I'd still like to see an allocWithAlignment() method or something, which
> may be implemented efficiently by allocators that can support it.

Per-allocation alignment requests are currently allowed (by setting the property transitorily) but indeed not really nice. I can see how HeapBlock could implement a nice alignedAllocate call but the others would kind of boringly pass it along.

Don't forget that it's always possible to define extra primitives for a given allocator (see e.g. relinquish or available). They should be migrated to official API status only if they could help composition in one way or another. In fact that's how I defined the API - I started with allocate()/deallocate() and a list of allocators I wanted to implement, and tried to get away with as few primitives as possible. For example FallbackAllocator makes owns() necessary etc.

> 2. I see some lines like this:
> assert(parent.alignment>=X.alignof);
> What if parent.alignment < X.alignof? If 'parent' is something with an
> inflexible alignment, like malloc or the GC, what is the proper
> (convenient) way to reconcile the requirement?

That assert is in Freelist and requires that the parent allocator returns memory aligned to at least pointer alignment, so as to write pointers at the front of the allocation. That's a really low bar, I think there's no need to worry about it. (If you do, defining a UnalignedFreelist is always an option.)

> 3. FreeList has some options; minSize, maxSize, maxNodes. When I'm using
> a freelist, the most important option to me is to be able to allocate
> new nodes in batches. I'd like an option added to control the batch
> size, so multiple new nodes are allocated in contiguous blocks when the
> pool grows. Perhaps add a 4th parameter; minBatchSize = 1? (to retain
> support for your existing logic batching small allocations into larger
> allocated blocks)
> The main reasons for this are cache/spatial locality of small
> allocations, and minimising overhead burden on the upstream allocator.

Good idea; it's what people often do anyway. Before sending this out I'd added at least the option to allocate several nodes at a time to fill memory more efficiently, see allocateFresh at https://github.com/andralex/phobos/blob/allocator/std/allocator.d#L1988. Allowing the user to choose the number of nodes in a batch is a good extension of that. (I think the default should be unbounded, i.e. let the freelist allocator decide depending on goodMallocSize of the parent.)

> 4. OT: Working with D struct's, you often encounter, for instance:
>
> structRegion(uintminAlign=platformAlignment)
> {
> privateBasicRegion!(minAlign)base;
> ...
>
> Doesn't this make you sad? It makes me sad quite regularly.
> Especially when the very next line is (often): alias base this;

I'm content with that and I think you should too.


Andrei

October 25, 2013
25-Oct-2013 03:22, deadalnix пишет:
> On Thursday, 24 October 2013 at 19:53:56 UTC, Andrei Alexandrescu wrote:
>> Hello,
>>
>>
>> I know it's been a long wait. Hopefully it was worth it. The alpha
>> release of untyped allocators is ready for tire-kicking and a test drive.
>>
>> Code: https://github.com/andralex/phobos/blob/allocator/std/allocator.d
>>
>> Dox: http://erdani.com/d/phobos-prerelease/std_allocator.html
>>
[snip]
>
> First, I love it !
>
> Now destroying :D
>
> The first thing I notice is that this module is dead unsafe. I'm not
> sure it belong to std. We should probably reserve that for a "guru" part
> of the standard lib. Putting some system function in the standard lib is
> OK, as they are packaged around concepts (range, array, algorithms, etc
> . . .) but an entire module dedicated to @system stuff seems like it
> belong to another place.

+1 on both counts. It's a @system module, incredibly convenient but it belongs to core.allocator;


-- 
Dmitry Olshansky
October 25, 2013
25-Oct-2013 16:52, Jacob Carlborg пишет:
> On 2013-10-25 02:01, Andrei Alexandrescu wrote:
>
>> Oddly enough this can be actually done.
>>
>> with (setAllocator!Mallocator)
>> {
>>     ...
>> }
>>
>> setAllcator returns an rvalue that changes the global allocator to the
>> Mallocator in the constructor, and restores it to whatever it was in the
>> destructor.
>
> Wouldn't this be very unsafe? Say you call another function inside the
> with-statement and that function assumes the standard GC for allocating
> memory.
>

Very true. To put it simply it's a disastrous idea that sadly is too easy to be ignored.

IMHO we'd better start with containers and refitting Phobos from built-in AA/arrays to user-defined containers. One interesting way there is to accept/adopt containers as OutputRange.

-- 
Dmitry Olshansky
October 25, 2013
On Friday, 25 October 2013 at 17:57:23 UTC, Dmitry Olshansky wrote:
> 25-Oct-2013 16:52, Jacob Carlborg пишет:
>> On 2013-10-25 02:01, Andrei Alexandrescu wrote:
>>
>>> Oddly enough this can be actually done.
>>>
>>> with (setAllocator!Mallocator)
>>> {
>>>    ...
>>> }
>>>
>>> setAllcator returns an rvalue that changes the global allocator to the
>>> Mallocator in the constructor, and restores it to whatever it was in the
>>> destructor.
>>
>> Wouldn't this be very unsafe? Say you call another function inside the
>> with-statement and that function assumes the standard GC for allocating
>> memory.
>>
>
> Very true. To put it simply it's a disastrous idea that sadly is too easy to be ignored.
>
> IMHO we'd better start with containers and refitting Phobos from built-in AA/arrays to user-defined containers. One interesting way there is to accept/adopt containers as OutputRange.
Did you mean to get rid of built-in arrays / kill int[] and replace it with Array!T?
October 25, 2013
On 2013-10-25 15:14:38 +0000, "Adam D. Ruppe" <destructionator@gmail.com> said:

> @safe void setAllocator(Allocator)(pure @safe void function() code) {}
> 
> just might work out.

I wonder what kind of things can be done in a pure function that takes no parameter and returns void. Not much I guess.

-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

October 25, 2013
25-Oct-2013 22:41, Namespace пишет:
> On Friday, 25 October 2013 at 17:57:23 UTC, Dmitry Olshansky wrote:
>> 25-Oct-2013 16:52, Jacob Carlborg пишет:
>>> On 2013-10-25 02:01, Andrei Alexandrescu wrote:
>>>
>>>> Oddly enough this can be actually done.
>>>>
>>>> with (setAllocator!Mallocator)
>>>> {
>>>>    ...
>>>> }
>>>>
>>>> setAllcator returns an rvalue that changes the global allocator to the
>>>> Mallocator in the constructor, and restores it to whatever it was in
>>>> the
>>>> destructor.
>>>
>>> Wouldn't this be very unsafe? Say you call another function inside the
>>> with-statement and that function assumes the standard GC for allocating
>>> memory.
>>>
>>
>> Very true. To put it simply it's a disastrous idea that sadly is too
>> easy to be ignored.
>>
>> IMHO we'd better start with containers and refitting Phobos from
>> built-in AA/arrays to user-defined containers. One interesting way
>> there is to accept/adopt containers as OutputRange.
> Did you mean to get rid of built-in arrays / kill int[] and replace it
> with Array!T?

Hm, arrays? Kill? No, they are incredibly nice for prototyping + they are very useful even as just slices.

What I mean is to make it easy to use Phobos stuff with other containers in place of built-ins, basically no hard-codding behind the scenes.

Typical offender is Appender - it's rigid, has dangerous API and doesn't support building anything but T[]. For this particular case see: http://d.puremagic.com/issues/show_bug.cgi?id=11138

Another one:
http://dlang.org/phobos/std_array.html#.array
It's trivially expendable to any other Array-like type, yet ATM it's hardwired.

O.T. I'd gladly kill built-in AA though just to save people a lot of time spent on debugging that crap. More precisely I'd keep AA _literals_ and give the user the means to construct any type of Key-->Value store out of it. It's too late probably.

-- 
Dmitry Olshansky
October 25, 2013
25-Oct-2013 02:29, Brad Roberts пишет:
> There was a comment in an earlier reply that's very relevant to mine.  A
> good demonstration of the utility of these classes is how much of the
> current (and proposed) garbage collector can be replaced by using this
> module.  For that to happen, the code needs to actually live in the
> runtime (at least as things are currently layered).
>
> On 10/24/13 12:54 PM, Andrei Alexandrescu wrote:
>> Hello,
>>
>>
>> I know it's been a long wait. Hopefully it was worth it. The alpha
>> release of untyped allocators is
>> ready for tire-kicking and a test drive.
>>
>> Code: https://github.com/andralex/phobos/blob/allocator/std/allocator.d
>>
>> Dox: http://erdani.com/d/phobos-prerelease/std_allocator.html
>>
>> Warning: this is alpha quality. Unit tests are thin, and there are no
>> benchmarks. Both would be
>> appreciated, particularly benchmarks to validate the gains (which I
>> speculate can be very sizable)
>> of custom-built, special-purpose allocators compared to traditional
>> allocators.
>>
>> I acknowledge I'm clearly in no position to evaluate this design. I
>> have been knocking around it for
>> long enough to have no idea how easy it is to get into it from the
>> outside, or how good it is. By
>> all signs I could gather this feels like good design, and one of the
>> best I've ever put together.
>> The allocators defined have an archetypal feeling, are flexible both
>> statically and dynamically, and
>> morph and combine in infinite ways.
>>
>> CAllocator and CAllocatorImpl make the link between the static and
>> dynamic worlds. Once an allocator
>> is assembled out of pieces and finely tuned, wrapping it in a dynamic
>> API is a snap.
>>
>> Please destroy! I've literally sweat as I'm sending this :o).
>>
>>
>> Andrei

Looks incredibly cool so far :)

Some thoughts:

- I don't like the name CAllocator. Whatever that C stands for it's ambiguous (Class, Cee, Caramel?).

- It may be only me but I _think_ it could be more useful to have a few specific interfaces then 1 fat CAllocator. I've come to dislike fat-interfaces with isSupported kludges but that's IMHO.

- I see that shrink primitive didn't make it... Well, on the upside the primitives count is really low.

- In description of chooseAtRuntime:
HeapBlock!chooseAtRuntime  --> HeapBlock!(Allocator, chooseAtRuntime)


-- 
Dmitry Olshansky
October 25, 2013
On Friday, 25 October 2013 at 19:03:14 UTC, Dmitry Olshansky wrote:
> 25-Oct-2013 22:41, Namespace пишет:
>> On Friday, 25 October 2013 at 17:57:23 UTC, Dmitry Olshansky wrote:
>>> 25-Oct-2013 16:52, Jacob Carlborg пишет:
>>>> On 2013-10-25 02:01, Andrei Alexandrescu wrote:
>>>>
>>>>> Oddly enough this can be actually done.
>>>>>
>>>>> with (setAllocator!Mallocator)
>>>>> {
>>>>>   ...
>>>>> }
>>>>>
>>>>> setAllcator returns an rvalue that changes the global allocator to the
>>>>> Mallocator in the constructor, and restores it to whatever it was in
>>>>> the
>>>>> destructor.
>>>>
>>>> Wouldn't this be very unsafe? Say you call another function inside the
>>>> with-statement and that function assumes the standard GC for allocating
>>>> memory.
>>>>
>>>
>>> Very true. To put it simply it's a disastrous idea that sadly is too
>>> easy to be ignored.
>>>
>>> IMHO we'd better start with containers and refitting Phobos from
>>> built-in AA/arrays to user-defined containers. One interesting way
>>> there is to accept/adopt containers as OutputRange.
>> Did you mean to get rid of built-in arrays / kill int[] and replace it
>> with Array!T?
>
> Hm, arrays? Kill? No, they are incredibly nice for prototyping + they are very useful even as just slices.
>
> What I mean is to make it easy to use Phobos stuff with other containers in place of built-ins, basically no hard-codding behind the scenes.
>
> Typical offender is Appender - it's rigid, has dangerous API and doesn't support building anything but T[]. For this particular case see: http://d.puremagic.com/issues/show_bug.cgi?id=11138
>
> Another one:
> http://dlang.org/phobos/std_array.html#.array
> It's trivially expendable to any other Array-like type, yet ATM it's hardwired.
>
> O.T. I'd gladly kill built-in AA though just to save people a lot of time spent on debugging that crap. More precisely I'd keep AA _literals_ and give the user the means to construct any type of Key-->Value store out of it. It's too late probably.

With which syntax? As far as e.g. int[string] (and not something ugly as Map!(string, int)) would stay what would be the problem to change the backend?