Custom Allocators

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
downgraded

Custom Allocators

Post by downgraded »

Whilst Irrlicht has its own memory management in the form of reference counting, it still uses the new/delete operators to allocate memory. I'd like the ability to supply my own custom allocators for Irrlicht objects (so I can allocate from a pool) - is this feature planned for the future? I could hack it in myself, but the I'd lose the ability to upgrade straight out of the box...

Basically, I'd prefer this rather than having to allocate/free new objects on the heap all the time.
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

i like the idea, but I haven't seen anyone complaining about garbage collection problems. maybe this is because nobody is allocating and destroying enough objects for it to be a problem, or perhaps most people do their allocation outside the game loop anyway.
have you experimented with the number of creates/deletes that start to cause problems? I'd be interested to know where the boundries are, I'm sure others would too
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

I also thought about this. The problem is: I only did something like that once before, and don't have a lot experience on this, so I don't know what the best way is to do this. In older projects, I implemented an own new operator. How would you do this? Replace any new / malloc operator in Irrlicht with a new function? What about the external libraries used by Irrlicht? Any hints/ideas/suggestions?
evolutional
Posts: 16
Joined: Mon Apr 11, 2005 2:32 pm
Location: LEEDS, England
Contact:

Post by evolutional »

Well, I don't really see it as being a huge implementation change for Irrlicht. I currently use a custom MemoryPool class which allocates a chunk of memory (customisable) in one go. Whenever an object is created from the pool it'll look at the freelist and allocate from there first, if not it'll take an object from the pre-allocated pool. If the pool becomes full, it'll automatically grow itself and allocate another chunk. When an object is Freed, it gets returned to the object pool and placed on the freelist. Chunk grow sizes can be customised in order to ensure optimal memory use.

So why do I do this? The main issues are that of speed and memory fragmentation. The standard new/delete operators do not care about where the memory they get comes from as long as it comes. Typically in a game we'll be allocating/deallocating a lot of memory more often than usual applications, often on every frame (especially with particle systems). Over time the heap will become fragmented which serves to slow down further allocations as a suitable memory chunk has to be searched for upon allocation. With a simple pool and freelist system the memory is only allocated once and is then recycled on future new/deletes.

Essentially you're replacing calls to:

Something *p = new Something();
delete p;

with:
Something *p = Manager.AllocSomething();
Manager.Free( p );

The 'AllocSomething' routine should be in charge of correctly constructing the object, just like the Free routines should handle destructing (unless you build this into the pool).

I had huge slowdown problems in a game I was working on, the main issue was down to the particle system. I initially believed it was due to my graphics card but I only had a few hundred particles flying around. Upon further investigation I found that it was down to the memory fragmentation caused by continually new/deleting the particles. I replaced the system with the memory pooling techniques and I found that the game became smoother and faster. It also benefitted by being simpler to garbage collect. All objects were within the pool so it's a case of freeing the pool to collect the garbage, much simpler than some schemes I've seen around (I've not looked into Irrlicht's).

The main drawback of this technique is that unless you want to override the new/delete operators and provide global pools for objects (nasty for threading) you must have a central system that can Alloc/Free the objects accordingly. As the user interface side of Irrlicht forces you to do this anyway (CreateXXX functions) it'd be the ideal place to start looking at such a system. I've not examined the rest of the code so I don't know how much extra work it'd be. This hasn't been a problem for me because I always ensure that an object has a way back to the 'Environment' (without using ugly singletons).

Feel free to ask any more information. I can send you my pool allocator if you need it.

evolutional (downgraded)
hybrid

Post by hybrid »

There is a memory pool available from boost.org. Could be a starting point, though I did not check the sources, yet. But I don't think that it would be wise to generally replace all memory handling by such a library. The optional memory allocation in STL is only used in special cases, for most occasions the default memory handling is ok.
aguest

Post by aguest »

I wonder...

Would it be necessary to new/free all the times? (per frame)
Could you not create objects once (max number of particles)
Then disable/enable them instead? linked list?

Allocating/deallocating is always gonna create fragmententation.
Unless you use one pool per object type, lots of pools.

Or did I misunderstand you?
Post Reply