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.
Custom Allocators
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
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
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:
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)
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
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
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?
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?