Thread overview | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 07, 2013 How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Since my last thread doesn't get much attention I like to ask here: How did you deal with temporary memory? Let's assume that the size is only known at runtime. I have this situation e.g. in Dgame in the capture method: I get the pixel data from my Window with glReadPixel but it is reversed. So I have to reverse it again, but I still need at least temporary memory for one pixel-line which stores the currently swapped pixels. So how would you solve such a situation? Since D doesn't offer VLA's and alloca is broken (besides the ugly syntax), I use a scoped wrapper (since scope doesn't do the job): ---- struct scoped(A : T[], T) { T[] arr; alias arr this; this(T[] arr) { this.arr = arr; writefln("Get %d %s's (ptr = %x)", arr.length, T.stringof, arr.ptr); } ~this() { GC.free(this.arr.ptr); this.arr = null; GC.minimize(); } } void main() { // need temp memory scoped!(int[]) arr = new int[n]; } ---- And what do you use? |
December 07, 2013 Re: How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Saturday, 7 December 2013 at 22:32:59 UTC, Namespace wrote:
> Since D doesn't offer VLA's and alloca is broken (besides the ugly syntax),
> I use a scoped wrapper (since scope doesn't do the job):
I like to use a helper template that defines a static array with a typical size. Then, if the runtime requirement is less than that, it can simply slice into the static array, and if not, then do the alloc/free pair.
|
December 07, 2013 Re: How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Saturday, 7 December 2013 at 23:21:05 UTC, Adam D. Ruppe wrote:
> On Saturday, 7 December 2013 at 22:32:59 UTC, Namespace wrote:
>> Since D doesn't offer VLA's and alloca is broken (besides the ugly syntax),
>> I use a scoped wrapper (since scope doesn't do the job):
>
> I like to use a helper template that defines a static array with a typical size. Then, if the runtime requirement is less than that, it can simply slice into the static array, and if not, then do the alloc/free pair.
You mean something like that?
----
struct Helper(T, uint StackSize = 128) {
static T[StackSize] buffer = void;
static T[] opCall(size_t n) {
if (n <= StackSize)
return buffer[0 .. n];
return new T[n];
}
}
void main() {
int[] arr = Helper!int(512);
}
----
|
December 07, 2013 Re: How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Saturday, 7 December 2013 at 23:26:05 UTC, Namespace wrote:
> You mean something like that?
Yes.
|
December 08, 2013 Re: How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Saturday, 7 December 2013 at 23:26:05 UTC, Namespace wrote:
> struct Helper(T, uint StackSize = 128) {
> static T[StackSize] buffer = void;
Using a static variable here means that there is only one such buffer per thread (and e.g. it wouldn't be possible to use the helper twice in the same call stack) - is this really what you want?
David
|
December 08, 2013 Re: How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On Sunday, 8 December 2013 at 00:05:42 UTC, David Nadlinger wrote:
> On Saturday, 7 December 2013 at 23:26:05 UTC, Namespace wrote:
>> struct Helper(T, uint StackSize = 128) {
>> static T[StackSize] buffer = void;
>
> Using a static variable here means that there is only one such buffer per thread (and e.g. it wouldn't be possible to use the helper twice in the same call stack) - is this really what you want?
>
> David
That is not what I want or what I use. But it seems that Adam D. Ruppe use such a thing. What would you use?
|
December 08, 2013 Re: How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Sunday, 8 December 2013 at 00:11:18 UTC, Namespace wrote:
> But it seems that Adam D. Ruppe use such a thing. What would you use?
I didn't pay close enough attention; I don't use static, just the same general pattern there of static array up to a certain size.
|
December 08, 2013 Re: How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Sunday, 8 December 2013 at 00:16:46 UTC, Adam D. Ruppe wrote:
> the same general pattern there of static array up to a certain size.
static array being "T[max_size]", not "static T[max_size]"
just so it uses the stack for most things.
|
December 08, 2013 Re: How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 08-Dec-2013 02:32, Namespace пишет: > Since my last thread doesn't get much attention I like to ask here: How > did you deal with temporary memory? Let's assume that the size is only > known at runtime. > I have this situation e.g. in Dgame in the capture method: I get the > pixel data from my Window with glReadPixel but it is reversed. So I have > to reverse it again, but I still need at least temporary memory for one > pixel-line which stores the currently swapped pixels. So how would you > solve such a situation? > > Since D doesn't offer VLA's and alloca is broken (besides the ugly syntax), > I use a scoped wrapper (since scope doesn't do the job): > > ---- > struct scoped(A : T[], T) { > T[] arr; > > alias arr this; > > this(T[] arr) { > this.arr = arr; > > writefln("Get %d %s's (ptr = %x)", arr.length, T.stringof, > arr.ptr); > } > > ~this() { > GC.free(this.arr.ptr); > this.arr = null; > GC.minimize(); This is slow. Just use malloc & free, why touch GC at all? > } > } > > void main() { > // need temp memory > scoped!(int[]) arr = new int[n]; > } > ---- > > And what do you use? -- Dmitry Olshansky |
December 08, 2013 Re: How do you deal with scoped allocations? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Saturday, 7 December 2013 at 22:32:59 UTC, Namespace wrote:
> Since my last thread doesn't get much attention I like to ask here: How did you deal with temporary memory? Let's assume that the size is only known at runtime.
> I have this situation e.g. in Dgame in the capture method: I get the pixel data from my Window with glReadPixel but it is reversed. So I have to reverse it again, but I still need at least temporary memory for one pixel-line which stores the currently swapped pixels. So how would you solve such a situation?
>
> Since D doesn't offer VLA's and alloca is broken (besides the ugly syntax),
> I use a scoped wrapper (since scope doesn't do the job):
>
> ----
> struct scoped(A : T[], T) {
> T[] arr;
>
> alias arr this;
>
> this(T[] arr) {
> this.arr = arr;
>
> writefln("Get %d %s's (ptr = %x)", arr.length, T.stringof, arr.ptr);
> }
>
> ~this() {
> GC.free(this.arr.ptr);
> this.arr = null;
> GC.minimize();
> }
> }
>
> void main() {
> // need temp memory
> scoped!(int[]) arr = new int[n];
> }
> ----
>
> And what do you use?
From my probably somewhat incomplete understanding of such things:
This is not a good use-case for the gc. Use the c heap or just let the gc do its job normally.
|
Copyright © 1999-2021 by the D Language Foundation