Andrei Alexandrescu wrote:
Sean Kelly wrote:
Andrei Alexandrescu wrote:
KennyTM~ wrote:
The best solution I can think of, without compiler modification is a struct/class that contains a static array member T[1024] and a dynamic array member T[] initialized to null; and the code chooses which member to use in the constructor. But this always occupies 1024*T.sizeof bytes and there will always be a conditional (if) sticked to all access methods.

This entire discussion gets me thinking - could an alternate stack be a good (or even better) solution? Consider a global per-thread "superstack" - a growable region that allocates memory in large chunks and makes sub-chunks accessible in a strictly LIFO manner. The primitives of the superstack are as follows:

void* SuperStack.allocate(size_t bytes);
void SuperStack.free(size_t bytes);
size_t SuperStack.slack();

The SuperStack's management is a singly-linked list of large blocks.

It's an implementation detail, but when the owner thread dies it should null the links for all the list nodes, assuming the data contained in those nodes can be shared across threads.

Damn straight it could free() them assuming it has malloc()ated them!

It wouldn't even need to return the memory to the OS. It could even defer that until the next run of the gc, possibly avoiding the need for slack. (So the first action of the gc would be drop the unused space from the superstacks; if that's enough, there's no need to do a full collect).
Of course that only makes sense if the OS allocation is slow.

Anyway, the idea sounds great to me. It can be faster than stack allocation in some cases, since it can result in less cache pollution (dramatically so in the case where you have tail recursion of a function which is allocating large arrays; all the return addresses stay next to each other on the stack, and the allocated arrays don't need to be touched when they're being deleted).

Reply via email to