CEGUI+Custom memory allocator

Discussion regarding the development of CEGUI itself - as opposed to questions about CEGUI usage that should be in the help forums.

Moderators: CEGUI MVP, CEGUI Team

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: CEGUI+Custom memory allocator

Postby Kulik » Fri Oct 15, 2010 11:29

Just a note here, I am playing with something related but not the same as e3d_alive2... I am trying to delegate CEGUI mem allocation to external libraries, not support alternative allocators. My goal is to delegate to Ogre's nedmalloc implementation.

Initial patch: http://harcov.czenet.com/kulik/CEGUI/custom_allocators.patch

User avatar
Mikademus
CEGUI MVP
CEGUI MVP
Posts: 130
Joined: Wed Mar 18, 2009 19:14

Re: CEGUI+Custom memory allocator

Postby Mikademus » Sun Oct 17, 2010 10:58

Posting to show support: I favour nedmalloc because it is highly efficient and with very small footprint, and from a quick look at your patch it seems like a well-designed solution (caveat: I am not well versed in the CEGUI internals!).

Jamarr
CEGUI MVP
CEGUI MVP
Posts: 812
Joined: Tue Jun 03, 2008 23:59
Location: USA

Re: CEGUI+Custom memory allocator

Postby Jamarr » Mon Oct 18, 2010 19:21

I glanced over the OGRE custom memory management, as well as Kulik's patch, and I think that this approach is very well conceived. It gives both the library and client the leverage to implement memory schemes according to their needs via both inherited and specified allocators. I do have one question though: should the client be able to re-define the inherited allocators? Eg these:

Code: Select all

+typedef MemoryStdAllocator AnimationAllocator;
+typedef MemoryStdAllocator AnimationInstanceAllocator;
+typedef MemoryStdAllocator EventAllocator;
+typedef MemoryStdAllocator FontAllocator;
+typedef MemoryStdAllocator GeometryBufferAllocator;
+typedef MemoryStdAllocator SingletonAllocator;
+typedef MemoryStdAllocator StringAllocator;
+typedef MemoryStdAllocator TextureAllocator;
+typedef MemoryStdAllocator WindowAllocator;


I also noticed an oddity in the patch on line 741: the destroyWindow() implementation was changed from delete window; too new window;?

Code: Select all

Index: include/CEGUIWindowFactory.h
===================================================================
--- include/CEGUIWindowFactory.h   (revision 2657)
+++ include/CEGUIWindowFactory.h   (working copy)
@@ -60,11 +60,11 @@
         T ## Factory() : WindowFactory( T::WidgetTypeName ) {}\
         Window* createWindow(const String& name)\
         {\
-            return new T (d_type, name);\
+            return new T(d_type, name);\
         }\
         void destroyWindow(Window* window)\
         {\
-            delete window;\
+            new window;\
         }\
     };\
     T ## Factory& get ## T ## Factory();
If somebody helps you by replying to your thread, upvote him/her as a thanks! Make sure to include your CEGUI.log and everything you tried when posting! And remember that we are not magicians!

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: CEGUI+Custom memory allocator

Postby Kulik » Mon Oct 18, 2010 19:34

Yeah client should be able to redefine the typedefs so different allocators can be used for various classes.

The oddity is already fixed, CE spotted it too. Thanks for the feedback! I will post a new version of the patch soon.

Leaked rumours: :wink:
CEGUI startup without custom allocators: 303639 msec
CEGUI startup with malloc allocator: 310553 msec
CEGUI startup with Ogre's nedmalloc: 176020 msec

The speedup is pretty impressive. Seems almost too good to be true to me. The biggest benefit is at startup/shutdown. CEGUI doesn't alloc/dealloc much during runtime.

Jamarr
CEGUI MVP
CEGUI MVP
Posts: 812
Joined: Tue Jun 03, 2008 23:59
Location: USA

Re: CEGUI+Custom memory allocator

Postby Jamarr » Mon Oct 18, 2010 20:04

Almost 45% decrease is pretty impressive. I wonder if users who use a lot of dynamic windows would see similar gains. I also wonder if nedmalloc (http://www.nedprod.com/programs/portable/nedmalloc/) should be the default allocator, or at least an easily configurable option. It appears to be a very good library.
If somebody helps you by replying to your thread, upvote him/her as a thanks! Make sure to include your CEGUI.log and everything you tried when posting! And remember that we are not magicians!

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: CEGUI+Custom memory allocator

Postby Kulik » Mon Oct 18, 2010 22:04

I think I will post some code on how to integrate CEGUI with nedmalloc, Ogre and perhaps some other libraries on Wiki, not sure if bundling these with CEGUI is the right thing. Remember that this is all experimental stuff, highly flammable. I think it should get released as disabled by default and if it works for most people, this could change but definitely not sooner :wink:

I am currently walking through classes, marking which ones should be custom allocated and which ones should not.

Jamarr
CEGUI MVP
CEGUI MVP
Posts: 812
Joined: Tue Jun 03, 2008 23:59
Location: USA

Re: CEGUI+Custom memory allocator

Postby Jamarr » Tue Oct 19, 2010 16:36

Indeed. I was thinking something along the xml and image codec options we have now...default to standard new/malloc, with an easily configurable option to use nedmalloc, as well as ogre memory managers.
If somebody helps you by replying to your thread, upvote him/her as a thanks! Make sure to include your CEGUI.log and everything you tried when posting! And remember that we are not magicians!

User avatar
Mikademus
CEGUI MVP
CEGUI MVP
Posts: 130
Joined: Wed Mar 18, 2009 19:14

Re: CEGUI+Custom memory allocator

Postby Mikademus » Tue Oct 19, 2010 16:52

From my experiences with nedmalloc, when you get the code stable it should probably be the default option. Nedmalloc seems very robust and highly efficient, it is the default iirc in OGRE, and seems to be increasingly used used in both open source and big-budget commercial software so any errors should have been hammered out of it by now. Also, most development is done in Win32, and by Ned's measurements nedmalloc is about seven times faster than the standard Win32 allocator, so it seems a natural feature to a MS Windows-heavy user base.

Timo
Not too shy to talk
Not too shy to talk
Posts: 24
Joined: Sun Feb 14, 2010 09:38

Re: CEGUI+Custom memory allocator

Postby Timo » Tue Oct 19, 2010 17:12

Just some nitpicking about the macros in Kulik's patch... :)
- delete[] operator destroys the elements in reverse order, so I think just for consistency CEGUI_DELETE_ARRAY_T should do the same.
- Bad things will happen if someone uses CEGUI_DELETE_T or CEGUI_DELETE_ARRAY_T inside an if...else statement. To prevent the macros from "stealing" the following else keyword they need to be enclosed in a block.

Here's how I would do these:

Code: Select all

#   define CEGUI_DELETE_T(ptr, T, Allocator) do{ if(ptr){(ptr)->~T(); Allocator::deallocateBytes((void*)ptr, __FILE__, __LINE__, __FUNCTION__);} }while(0)
#   define CEGUI_DELETE_ARRAY_T(ptr, T, count, Allocator) do{ if(ptr){for (size_t b = count; b-- > 0;) { (ptr)[b].~T();} Allocator::deallocateBytes((void*)ptr, __FILE__, __LINE__, __FUNCTION__);} }while(0)

Code: Select all

#   define CEGUI_DELETE_T(ptr, T, Allocator) do{ if(ptr){(ptr)->~T(); Allocator::deallocateBytes((void*)ptr);} }while(0)
#   define CEGUI_DELETE_ARRAY_T(ptr, T, count, Allocator) do{ if(ptr){for (size_t b = count; b-- > 0;) { (ptr)[b].~T();} Allocator::deallocateBytes((void*)ptr);} }while(0)

What it comes to including nedmalloc with CEGUI and possibly having it enabled by default, I'm actually for it. That way even those who don't care or don't understand about allocators can still get the benefits. If the patch is just to allow the replacement of the allocator, then to be honest I don't see it as quite as useful. Because the people who do care about memory management, can already use a custom allocator somewhat easily by overloading the new operator globally. (Though I admit not everyone likes doing that.)

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: CEGUI+Custom memory allocator

Postby Kulik » Tue Oct 19, 2010 18:56

Thanks for the nitpicking Timo ;-) I have actually run into such problems and have solved them by scoping the macros with just {}, does this approach (do {} while(0)) have any advantages over scoping? Thanks..

Whether nedmalloc will be included in the distribution is still undecided, binary CEGUI SDKs will definitely be without allocators, you will have to compile CEGUI yourself to get them... However I guess I could include some wrappers to make it easier to use nedmalloc and Ogre.

Timo
Not too shy to talk
Not too shy to talk
Posts: 24
Joined: Sun Feb 14, 2010 09:38

Re: CEGUI+Custom memory allocator

Postby Timo » Tue Oct 19, 2010 19:38

Kulik wrote:Thanks for the nitpicking Timo ;-) I have actually run into such problems and have solved them by scoping the macros with just {}, does this approach (do {} while(0)) have any advantages over scoping? Thanks..

Only the advantage that you can (and you have to) always put a semicolon after it, whereas you can't always put semicolon after {}. So the macro behaves more like normal function call.

JerryM
Just popping in
Just popping in
Posts: 9
Joined: Wed Oct 20, 2010 02:15

Re: CEGUI+Custom memory allocator

Postby JerryM » Wed Oct 20, 2010 02:23

Kulik wrote:I am currently walking through classes, marking which ones should be custom allocated and which ones should not.

Just making a note that most real games have very strict heap requirements. It would be preferable if all heap allocations could be customized, especially with a library like CEGUI that must be run entirely in an already tight rendering thread. Use of the system heap is bad, bad, bad.

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: CEGUI+Custom memory allocator

Postby Kulik » Wed Oct 20, 2010 08:50

Timo wrote:
Kulik wrote:Thanks for the nitpicking Timo ;-) I have actually run into such problems and have solved them by scoping the macros with just {}, does this approach (do {} while(0)) have any advantages over scoping? Thanks..

Only the advantage that you can (and you have to) always put a semicolon after it, whereas you can't always put semicolon after {}. So the macro behaves more like normal function call.

You're right, scoping allows the semicolon whilst do {} while(false) requires it so the latter is definitely better.

JerryM wrote:
Kulik wrote:I am currently walking through classes, marking which ones should be custom allocated and which ones should not.

Just making a note that most real games have very strict heap requirements. It would be preferable if all heap allocations could be customized, especially with a library like CEGUI that must be run entirely in an already tight rendering thread. Use of the system heap is bad, bad, bad.

So are you suggesting that everything in CEGUI should be custom allocated? The problem with this is quite simple, I found out (just by experiment) that for some classes (especially really small ones) custom allocation slows things down. It's not very noticeable but the difference is there. Ogre for example custom allocates everything except really small classes. I haven't yet researched this so the decision isn't final but I was going to skip CEGUI::colour, because when it's custom allocated it gets slower. I think this could be related to some compiler optimisations that are disabled when new and delete are overriden... I will look into it a bit more by the end of the week.

JerryM
Just popping in
Just popping in
Posts: 9
Joined: Wed Oct 20, 2010 02:15

Re: CEGUI+Custom memory allocator

Postby JerryM » Wed Oct 20, 2010 12:23

Kulik wrote:So are you suggesting that everything in CEGUI should be custom allocated? The problem with this is quite simple, I found out (just by experiment) that for some classes (especially really small ones) custom allocation slows things down. It's not very noticeable but the difference is there. Ogre for example custom allocates everything except really small classes. I haven't yet researched this so the decision isn't final but I was going to skip CEGUI::colour, because when it's custom allocated it gets slower. I think this could be related to some compiler optimisations that are disabled when new and delete are overriden... I will look into it a bit more by the end of the week.
Yes. Perhaps not by default for all users, but it would be really great if it was there for more advanced users.

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: CEGUI+Custom memory allocator

Postby Kulik » Sat Oct 23, 2010 21:48

OK, I replaced the delete macros with Timo's code and finished up inheriting everything imaginable from AllocatedObject ;-)

The problem right now is that there are tons of allocator typedefs, I would like to merge some of them to make maintenance easier.

The only up to date allocator is the Ogre one right now.

Code: Select all


typedef ::Ogre::GeneralAllocPolicy DefaultAllocator;

typedef DefaultAllocator AnimationAllocator;
typedef DefaultAllocator AnimationInstanceAllocator;
typedef DefaultAllocator BiDiVisualMappingAllocator;
typedef DefaultAllocator DynamicModuleAllocator;
typedef DefaultAllocator EventAllocator;
typedef DefaultAllocator EventArgsAllocator;
typedef DefaultAllocator FactoryModuleAllocator;
typedef DefaultAllocator FontAllocator;
typedef DefaultAllocator FormattedRenderedStringAllocator;
typedef DefaultAllocator GeometryBufferAllocator;
typedef DefaultAllocator ImageAllocator;
typedef DefaultAllocator ImageCodecAllocator;
typedef DefaultAllocator ImagesetAllocator;
typedef DefaultAllocator InterpolatorAllocator;
typedef DefaultAllocator LoggerAllocator;
typedef DefaultAllocator PropertyAllocator;
typedef DefaultAllocator RawDataContainerAllocator;
typedef DefaultAllocator RegexMatcherAllocator;
typedef DefaultAllocator RenderedStringAllocator;
typedef DefaultAllocator RendererAllocator;
typedef DefaultAllocator RenderEffectAllocator;
typedef DefaultAllocator RenderEffectFactoryAllocator;
typedef DefaultAllocator RenderingSurfaceAllocator;
typedef DefaultAllocator RenderQueueAllocator;
typedef DefaultAllocator RenderTargetAllocator;
typedef DefaultAllocator ResourceProviderAllocator;
typedef DefaultAllocator SchemeAllocator;
typedef DefaultAllocator ScriptModuleAllocator;
typedef DefaultAllocator SingletonAllocator;
typedef DefaultAllocator StringAllocator;
typedef DefaultAllocator STLAllocator;
typedef DefaultAllocator SubscriberAllocator;
typedef DefaultAllocator TextureAllocator;
typedef DefaultAllocator TrivialAllocator;
typedef DefaultAllocator WindowAllocator;
typedef DefaultAllocator WindowFactoryAllocator;
typedef DefaultAllocator WindowRendererAllocator;
typedef DefaultAllocator WindowRendererModuleAllocator;
typedef DefaultAllocator XMLAttributesAllocator;
typedef DefaultAllocator XMLHandlerAllocator;
typedef DefaultAllocator XMLParserAllocator;
typedef DefaultAllocator XMLSerializerAllocator;


I would definitely merge all *ModuleAllocator and all *FactoryAllocator classes. I want to allow as much flexibility as possible but I don't want to go overboard.
TrivialAllocator is used for classes that are trivial and unlikely to be heap allocated (Vector2, 3, colour, ColourRect, ...).
What else should possibly get merged? I imagine 95% of the devs are going to use one allocator for everything anyways so making it simpler for the 95% while making it flexible enough for the remaining 5% is my goal.

Since my server died, I have filled the request in mantis and uploaded the latest patch (it still is far from stable and clean code!) - http://cegui.org.uk/mantis/view.php?id=407

EDIT: I think I will go the template specialisation way in the end (same as Ogre3D). This will make it easy to set one default allocator and specialise the template for any exceptions.


Return to “CEGUI Library Development Discussion”

Who is online

Users browsing this forum: No registered users and 1 guest