Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

How can I avoid using default new() to create each object?

My previous demo had very unpleasant framerate hiccups during dynamic memory allocations (usually, when arrays are resized), and creating lots of small objects which often contain one pointer to some DirectX resource seems like an awful lot of waste.

I'm thinking about:

  1. Creating a master look-up table to refer to objects by handles (for safety & ease of serialization), much like EntityList in source engine

  2. Creating a templated object pool, which will store items contiguously (more cache-friendly, fast iteration, etc.) and the stored elements will be accessed (by external systems) via the global lookup table.

The object pool will use the swap-with-last trick for fast removal (it will invoke the object's ~destructor first) and will update the corresponding indices in the global table accordingly (when growing/shrinking/moving elements). The elements will be copied via plain memcpy().

Is it a good idea? Will it be safe to store objects of non-POD types (e.g. pointers, vtable) in such containers?

Related post: Dynamic Memory Allocation and Memory Management

share|improve this question
    
What language are you using? Why are you resizing arrays? Do you really have content that are so unpredictable that you can't reasonably simply make arrays that are big enough? –  eBusiness Apr 10 '12 at 13:25
    
i'm using C++ on Windows. all my game objects or pointers to them (including resources like meshes,textures) are stored in separate arrays which grow when a new object is created or an asset is loaded. i guess i should load everything beforehand, but ability to create the objects at runtime is essential for the editor. –  GameDevEnthusiast Apr 10 '12 at 14:05
    
The fact that you're doing this kind of memory allocation at runtime means that you've a more fundamental design issue that you need to resolve. Any direct answer to your question may fix the symptoms for sure, but the underlying design issue will still remain. Better to focus on that first, then see if you need to do anything about your allocators afterwards. –  Darth Satan Apr 10 '12 at 16:31

3 Answers 3

Memory pools or object pools are a very common practice in game programming. Another common practice in console games is to allocate everything in module-specific pools to "budget" memory and have precise control over when and where allocation occurs.

Some years ago I asked advice on which strategy to go with a game I was making: http://stackoverflow.com/questions/1964722/one-big-pool-or-several-type-specific-pools

The strategy to use is mostly dependant on your game but anyway, making sure no allocation/deallocation is being done while the game is running is a golden rule of thumb. It can be broken if the game state might vary depending on external informations, like when you work on MMO games. But then, having memory pools for several categories of size of objects (instead of pool of objects) might be a good idea to keep the memory as stable as possible.

Pooling should work for any kind of object, depending on the strategy. What's important is that the full type is known by the pool to allocate enough memory, then do whatever you want with the object. The other thing to not forget is to let the pool know when the object can be released to be used later (without deallocating it's memory).

share|improve this answer
    
Thanks a lot! The linked content was very useful!i'll try the object pool approach where max. allowed size of each pool will be set in the editor (or gathered from test runs, 'profiling'). –  GameDevEnthusiast Apr 10 '12 at 14:09

I'd consider "resizing" arrays to be an emergency solution, avoid it as far as possible.

If you truly need dynamic size tables you should build them in two layers. Make a small master table that only contain pointers to fixed size sub tables of the desired table content. When the last sub table is close to full you allocate a new one. You could for instance decide to make a master table of 1024 pointer slots, and have each sub table contain 1024 objects, thus the overhead will never be more than a little over a thousand objects and 1024 pointers, yet you have got room for 1048576 objects while only needing to do simple memory allocations at runtime.

share|improve this answer
The elements will be copied via plain memcpy().

And... when you come to apply this to your Text objects? Never, ever, use memcpy when you can use std::copy.

Your intended goal is laudable but your implementation details seem more than a little sketchy to me. Boost comes with a pre-built pool allocator you can use which likely put a lot more thought and time into this than you did, and works for any type.

share|improve this answer
    
i intend on storing non-POD types (with virtual functions and smart pointers) in such objects pools. The objects (memory) will sometimes be moved to improve data locality (practical example: inactive lights are moved to the end of the list -> no branches in the deferred lighting loop). For safer copying I'll use something like "type_traits::is_bitwise_copyable". –  GameDevEnthusiast Apr 10 '12 at 16:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.