Jump to page: 1 2 3
Thread overview
Often repeated array allocations
Jul 20, 2013
Namespace
Jul 20, 2013
Dmitry Olshansky
Jul 20, 2013
Ali Çehreli
Jul 21, 2013
Dmitry Olshansky
Jul 20, 2013
Namespace
Jul 21, 2013
Dmitry Olshansky
Jul 21, 2013
Namespace
Jul 21, 2013
bearophile
Jul 21, 2013
Namespace
Jul 22, 2013
monarch_dodra
Jul 22, 2013
Namespace
Jul 22, 2013
David
Jul 22, 2013
Namespace
Jul 21, 2013
Dmitry Olshansky
Jul 20, 2013
bearophile
Jul 20, 2013
Namespace
Jul 20, 2013
bearophile
Jul 20, 2013
Namespace
Jul 20, 2013
bearophile
Jul 21, 2013
Namespace
Jul 21, 2013
Jacob Carlborg
Jul 21, 2013
Namespace
Jul 22, 2013
Jacob Carlborg
Jul 21, 2013
bearophile
Jul 21, 2013
Namespace
Jul 21, 2013
bearophile
July 20, 2013
Let us assume we have a method of a class which is used often and the method is called periodically and must allocate every time a array between 100 and 4000 elements. What would you do?

1. Simple: float[] array;
2. Reserve: float[] array; array.reserve(N); /// N is a parameter value
3. Use manual memory allocation (e.g. with malloc) and free the memory immediately at the end of the scope.
4. Use stack allocated memory (But maybe 4000 is too big?)

Currently I would prefer #3, the manual memory allocation because I can then control when _exactly_ the memory is released. But I want to hear other opinions. :)
July 20, 2013
21-Jul-2013 00:19, Namespace пишет:
> Let us assume we have a method of a class which is used often and the
> method is called periodically and must allocate every time a array
> between 100 and 4000 elements. What would you do?
>
> 1. Simple: float[] array;
> 2. Reserve: float[] array; array.reserve(N); /// N is a parameter value
> 3. Use manual memory allocation (e.g. with malloc) and free the memory
> immediately at the end of the scope.
> 4. Use stack allocated memory (But maybe 4000 is too big?)
>
> Currently I would prefer #3, the manual memory allocation because I can
> then control when _exactly_ the memory is released. But I want to hear
> other opinions. :)

5. Keep a TLS scratch pad buffer (static  class member) for said 100-4000 floats and re-use it.



-- 
Dmitry Olshansky
July 20, 2013
Namespace:

> But I want to hear other opinions. :)

D also supports alloca(), that for 1D arrays is almost bearable.

See also:
http://d.puremagic.com/issues/show_bug.cgi?id=9832

Bye,
bearophile
July 20, 2013
On 07/20/2013 01:22 PM, Dmitry Olshansky wrote:

> 21-Jul-2013 00:19, Namespace пишет:
>> Let us assume we have a method of a class which is used often and the
>> method is called periodically and must allocate every time a array
>> between 100 and 4000 elements. What would you do?

> 5. Keep a TLS scratch pad buffer (static  class member) for said
> 100-4000 floats and re-use it.

As long as the function finishes with that buffer, there shouldn't be reentrancy issues in general. But if the function calls the same function, say on another object perhaps indirectly, then the two objects would be sharing the same buffer:

class C
{
    void foo() {
        /* modify the static buffer here */
        auto c = new C();
        c.foo();
        /* the static buffer has changed */
    }
}

Ali

July 20, 2013
On Saturday, 20 July 2013 at 20:22:56 UTC, Dmitry Olshansky wrote:
> 21-Jul-2013 00:19, Namespace пишет:
>> Let us assume we have a method of a class which is used often and the
>> method is called periodically and must allocate every time a array
>> between 100 and 4000 elements. What would you do?
>>
>> 1. Simple: float[] array;
>> 2. Reserve: float[] array; array.reserve(N); /// N is a parameter value
>> 3. Use manual memory allocation (e.g. with malloc) and free the memory
>> immediately at the end of the scope.
>> 4. Use stack allocated memory (But maybe 4000 is too big?)
>>
>> Currently I would prefer #3, the manual memory allocation because I can
>> then control when _exactly_ the memory is released. But I want to hear
>> other opinions. :)
>
> 5. Keep a TLS scratch pad buffer (static  class member) for said 100-4000 floats and re-use it.

TLS scratch pad buffer?
July 20, 2013
On Saturday, 20 July 2013 at 20:34:50 UTC, bearophile wrote:
> Namespace:
>
>> But I want to hear other opinions. :)
>
> D also supports alloca(), that for 1D arrays is almost bearable.
>
> See also:
> http://d.puremagic.com/issues/show_bug.cgi?id=9832
>
> Bye,
> bearophile

Yeah, but aren't 4000 elements a bit much for a stack allocated array?
July 20, 2013
Namespace:

> Yeah, but aren't 4000 elements a bit much for a stack allocated array?

4000 floats take about 16 KB. If your function is not recursive and it's not much transitively recursive, then I think it's acceptable. But how much stack are your other functions using? You have to estimate if you have enough stack space. Today it's very easy to have 50+ MB of stack, if necessary. DMD on Windows supports a linker command like this:

 -L/STACK:200000000

Bye,
bearophile
July 20, 2013
On Saturday, 20 July 2013 at 21:39:31 UTC, bearophile wrote:
> Namespace:
>
>> Yeah, but aren't 4000 elements a bit much for a stack allocated array?
>
> 4000 floats take about 16 KB. If your function is not recursive and it's not much transitively recursive, then I think it's acceptable. But how much stack are your other functions using? You have to estimate if you have enough stack space. Today it's very easy to have 50+ MB of stack, if necessary. DMD on Windows supports a linker command like this:
>
>  -L/STACK:200000000
>
> Bye,
> bearophile

So, you would never allocate with float[]?
July 20, 2013
Namespace:

> So, you would never allocate with float[]?

Generally in D I allocate on the heap with new, and once in a while with minimallyInitializedArray. Stack-allocation is left for situations where max performance is needed. Like you have to build a tree of string distances, and you use a Levenshtein distance to compute them. Usually a Levenshtein distance needs one buffer, or two. If you want to put one million of strings in such tree of distances, you can't allocate one billions of buffers, it's too much wasted time. For such case I allocate the Levenshtein buffer with an alloca (or I allocate the buffer before the function, etc, there are many ways).

I think the usual D code uses too much heap allocation. Allocations on the heap are slow. If you take a look at modern Ada code (like Ada2012 code) you see very little heap allocations, or no heap allocations at all :-) Probably Rust code will avoid lot of of heap allocations.

Bye,
bearophile
July 21, 2013
But D isn't like Ada. It's more like C++ and there Heap allocations is often used too.
It would be really cool if we had allocators already.
Something like:
----
with (AllocatorX) { /// will use malloc and free instead of calling the GC
    float[] arr;
    arr ~= 42;
}
----

And I still don't know what a 'TLS scratch pad buffer' is.
« First   ‹ Prev
1 2 3