C++ Memory Management for Texture Streaming in Videogames

c++defragmentationmemory-management

this is a "hard" question. I've found nothing interesting over the web.

I'm developing a Memory Management module for my company. We develop games for next-gen consoles (Xbox 360, PS3 and PC… we consider PC a console!).

We'll need in future, for our next games, to handle texture streaming for large game worlds that cannot be loaded all in main console memory (not talking about PC for now).

We are going to stream at the beginning hi-res mipmaps of textures (that is about 70% of the size of world data). Maybe in the future we'll have to stream also geometry, smaller mipmaps, audio, etc.

I'm developing a Memory Manager for that issue, focused on X360 (because over PS3 we can use host memory and the associated, auto-defragmenting GMM allocator).

The problem I'm facing is the following: We have decided to reserve a specific Memory Area for texture streaming (for example 64 Megabytes) and we want to handle all allocations and deallocations in that area. We have allocated the area at the beginning of the application and the area is Physically guaranteed to be contiguous (not just virtually, cause we need to store textures there).

I've implemented an auto defragmenting allocator, using handles instead of pointers. Time is not an issue, the problem is memory fragmentation. In game we continuously load and unload streaming targets, so we'd like to use the maximum amount of our buffer (64 Megabytes).

With this allocator we can use all of the allocated space but the defragmentation routine works in an unaccettable time (sometimes 60 milliseconds, more than a frames!) while the algorithm is not too bad… there are just too meny unevitable memcpy!

I'm looking for a solution to solve this issue. I'd like to find at least a good paper, or a post-mortem, or someone who have faced the same problem of mine.

Now I'm choosing between two strategies:
1) move the defragmentation routine on a dedicated thread (good for X360 with 6 hw threads, bad for PS3 with just a hw thread… and don't tell me to use SPU's!) with all multithreading problems of locking regions, of accessing a region who is being moved,…
2) find an "incremental" solution to defragmentation problem: we can give each frame a time budget (for example up to 1 millisecond) for defragmentation and the Memory Manager will do what it can do in the budget each frame.

Can someone tell me his experience about?

Best Solution

I did a lot of study recently regarding memory management and this is the most informative and helpful article I found on the net.

http://www.ibm.com/developerworks/linux/library/l-memory/

Based on that paper the best and fastest result you will get is to divide your 64 MB into equal sized chunks. The size of chunks will depend on your object size. And allocate or deallocate a full chunk at a time. It's

  1. Faster than incremental garbage collection.
  2. Simpler.
  3. And solves that "too much fragmantation" problem by some amount.

Read it, you will find excellent information on every possible solution there is and merits and demerits for each.