www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Memory Pools support in Phobos

reply F. Almeida <francisco.m.almeida gmail.com> writes:
A short question.

Currently, there are plans to deprecate the original manual memory management
features (as borrowed from C++), because unlike C++, D has built-in GC. The
library provided alternative pointed out in TDPL, clear(), is still under
development, it seems.

I'm happy to have read here that it will not call the object constructor, which
will not only reduce its impact on performance substantially, but also provide
"cleared" objects with a recognizable state. This is much better than
"resetting" them.

Someone else pointed out that the same behaviour (reverting all fields to .init
state and flagging the object as cleared) could actually be assigned to the
"delete" keyword. This too sounds like a good idea, because old D2 code could,
at least partially, retroactively become memory safe. Not to mention the
familiarity.

Regardless of the direction chosen for delete and clear(), Phobos is still
lacking in functions that ease the management of the C heap.

Boost has an interesting memory pool mechanism for C++. I think that Phobos
would benefit from such a library. Are there plans to implement an equivalent
in D?
Nov 12 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
F. Almeida:

 Regardless of the direction chosen for delete and clear(), Phobos is still
lacking in functions that ease the management of the C heap.

I think Andrei agrees with you, he discussed this a bit in past. I agree, adding few manual memory management functions/structs to Phobos will help a lot lower level coding. The good thing is that I think only one or few hundreds of lines of code may be enough to solve most of this problem. The data structures I'd like in this manual memory management Phobos module: 1) In my dlibs1 I have a "simple" struct that acts like a pool: struct Foo {} // some struct alias MemoryPool!Foo FooPool; And then you may ask FooPool: a new Foo, clear them all, deallocate them all (if you want you may also add a freelist of Foo so you may deallocate only one of them). Surely there are ways to design something more general than this, but in lot of cases this was enough for me, and I have seen programs become twice faster just using this MemoryPool. 2) A second data structure that may be useful is a memory arena, where you allocate different sized objects. 3) A third data structure I'd like in Phobos is a hierarchical allocator, it's very easy to use, easy to implement, but it is powerful: http://swapped.cc/halloc/ 4) This old code by Walter, the mem.c/mem.h memory management utility is partially obsolete, but some of its ideas may be useful for people that use the C heap manually from D: http://c.snippets.org/code/temp/snip-c.zip 5) This is a kind of hack, but helps a little: a function that carves a whole 2D dynamic array of dynamic arrays matrix out of a single C-heap allocated memory object (it has to respect alignments of its basic item, so sometimes it adds a bit of padding). This helps a little reduce memory usage and sometimes increases performance because of higher cache coherence. 6) An unsafe growable dynamic array allocated backwards on the stack :-) This works, but you need to use it carefully, not defining new variables in the middle. Bye, bearophile
Nov 12 2010
parent Fawzi Mohamed <fawzi gmx.ch> writes:
One structure that I found very useful in blip  is a set of numa node  
local caches that can be used for pools/freelists.
One can create such a "numa aware" pool with something like (see  
blip.container.Pool & blip.container.Cache)

	PoolI!(T) myPool=cachedPool(function T(PoolI!(T)p) { auto res=new T;  
res.pool=p; return res; });

One can also create such a pool with two functions addPool/rmPool that  
do a reference counting to allocate the pool if needed (this is used  
for example in loops for the context structures.

This is still less efficient than it should be because D1doesn't have  
TLS support like D2 for the default cache storage, but has the correct  
scaling (another place where blip suffer due to this is the current  
task, that also uses TLS).

Fawzi
On 12-nov-10, at 13:49, bearophile wrote:

 F. Almeida:

 Regardless of the direction chosen for delete and clear(), Phobos  
 is still lacking in functions that ease the management of the C heap.

I think Andrei agrees with you, he discussed this a bit in past. I agree, adding few manual memory management functions/structs to Phobos will help a lot lower level coding. The good thing is that I think only one or few hundreds of lines of code may be enough to solve most of this problem. The data structures I'd like in this manual memory management Phobos module: 1) In my dlibs1 I have a "simple" struct that acts like a pool: struct Foo {} // some struct alias MemoryPool!Foo FooPool; And then you may ask FooPool: a new Foo, clear them all, deallocate them all (if you want you may also add a freelist of Foo so you may deallocate only one of them). Surely there are ways to design something more general than this, but in lot of cases this was enough for me, and I have seen programs become twice faster just using this MemoryPool. 2) A second data structure that may be useful is a memory arena, where you allocate different sized objects. 3) A third data structure I'd like in Phobos is a hierarchical allocator, it's very easy to use, easy to implement, but it is powerful: http://swapped.cc/halloc/ 4) This old code by Walter, the mem.c/mem.h memory management utility is partially obsolete, but some of its ideas may be useful for people that use the C heap manually from D: http://c.snippets.org/code/temp/snip-c.zip 5) This is a kind of hack, but helps a little: a function that carves a whole 2D dynamic array of dynamic arrays matrix out of a single C-heap allocated memory object (it has to respect alignments of its basic item, so sometimes it adds a bit of padding). This helps a little reduce memory usage and sometimes increases performance because of higher cache coherence. 6) An unsafe growable dynamic array allocated backwards on the stack :-) This works, but you need to use it carefully, not defining new variables in the middle. Bye, bearophile

Nov 12 2010