Custom memory allocators
Posted: Fri May 16, 2008 10:33 pm
This feature point is well overdue and has been languishing since my student form last year's Summer of Code didn't come back in the end. I've had it on my 'you really ought to do this' list for some time, but now we're getting down to the wire I decided to bite the bullet and try to get it in for 1.6 as was originally promised. I had some recent feedback from someone who has some experience in this area and while I don't have any code I can use from them, they indicated to me the sorts of things I should be looking at to improve the SoC version.
I've taken what was done in SoC last year and stripped it down to something leaner and more manageable - the original intention was to have a framework suitable for new leak detection / memory profiling too but there's no time to polish that, and besides many allocator systems you might want to re-use already have that built-in. In addition, some of what was done in SoC was good in theory, and based on sound principles, but after taking advice it was a little too flexible, and all those template instantiations would have an additional (code size) cost that wasn't justified. It was also a little over complicated to implement a new allocator.
I've got a version working and it's looking good for inclusion in 1.6. There are essentially 2 issues:
1) Overriding new/delete for Ogre classes
2) Overriding the STL container allocators
I've decided to have 2 different 'holder' classes for this, Ogre::AllocatedObject (suitable for subclassing objects from) and Ogre::STLAllocator (suitable for being passed as a template parameter to an STL container). Both are templated classes but take a simple 1-level set of parameters (instead of the multi-level used previously), most importantly identifying the 'policy' class which actually does the allocation. This class only has to implement allocation, deallocation and be able to report the maximum size of memory it can allocate in a single block (required for STL containers). The custom allocator is thus much simpler than before, and the same policy class can be a back-end to both AllocatedObject and STLAllocator, although you can define as many as you like.
I plan to have be 2 built-in policies OOTB, one simple one which uses malloc/free as usual, and one which uses nedmalloc. Users are free to add their own of course, provided you rebuild Ogre with your allocators configured.
For maximum flexibility, I will be typedeffing all the allocators individually (e.g. EntityAlloc, SceneNodeAlloc, PointerVectorAlloc) so that people can tweak them individually. All the defaults will point back to the same type but obviously with some judicious typedefs you could make allocators which allocate specific types of objects from particular pools or using particular strategies.
It may be a couple of days until you see anything in SVN, I'm ping-ponging between Windows, OS X and Linux to make sure I don't break anything as I get the main core up and running. But I'm pretty confident it should be ready for 1.6 as originally promised.
I've taken what was done in SoC last year and stripped it down to something leaner and more manageable - the original intention was to have a framework suitable for new leak detection / memory profiling too but there's no time to polish that, and besides many allocator systems you might want to re-use already have that built-in. In addition, some of what was done in SoC was good in theory, and based on sound principles, but after taking advice it was a little too flexible, and all those template instantiations would have an additional (code size) cost that wasn't justified. It was also a little over complicated to implement a new allocator.
I've got a version working and it's looking good for inclusion in 1.6. There are essentially 2 issues:
1) Overriding new/delete for Ogre classes
2) Overriding the STL container allocators
I've decided to have 2 different 'holder' classes for this, Ogre::AllocatedObject (suitable for subclassing objects from) and Ogre::STLAllocator (suitable for being passed as a template parameter to an STL container). Both are templated classes but take a simple 1-level set of parameters (instead of the multi-level used previously), most importantly identifying the 'policy' class which actually does the allocation. This class only has to implement allocation, deallocation and be able to report the maximum size of memory it can allocate in a single block (required for STL containers). The custom allocator is thus much simpler than before, and the same policy class can be a back-end to both AllocatedObject and STLAllocator, although you can define as many as you like.
I plan to have be 2 built-in policies OOTB, one simple one which uses malloc/free as usual, and one which uses nedmalloc. Users are free to add their own of course, provided you rebuild Ogre with your allocators configured.
For maximum flexibility, I will be typedeffing all the allocators individually (e.g. EntityAlloc, SceneNodeAlloc, PointerVectorAlloc) so that people can tweak them individually. All the defaults will point back to the same type but obviously with some judicious typedefs you could make allocators which allocate specific types of objects from particular pools or using particular strategies.
It may be a couple of days until you see anything in SVN, I'm ping-ponging between Windows, OS X and Linux to make sure I don't break anything as I get the main core up and running. But I'm pretty confident it should be ready for 1.6 as originally promised.