Skip to main content
gamedev.net
🔒 Locked

memory management

Started by evillive2 7 replies 700+ views
Original Post
evillive2
evillive2
Ok, I am still designing my application and was going through some ideas. If I know basicly the max amount of memory my program is going to use and I grab that memory at the beginning something like this: // any following code is of course just an outline // for use as a general reference // pointer to the beginning of the memory block void *memory_block = calloc( 1, MAX_MEMORY_SIZE ); // pointer to the current location in the memory block void *position = memory_block; then I use something like this to allocate memory to individual objects: void *alloc_new( size_t mem_needed ) { void *pMem; /* maybe here check if there is a block of memory before position that is no longer in use by an object of the same type/size that we can use instead of advancing position */ // else pMem = position; position += mem_needed+1; return pMem; } OBJECT_TYPE *pObj = (OBJECT_TYPE*)alloc_new( sizeof(*pObj) ); Are there any advantages to be had by grabbing the memory right away instead of dynamicly grabbing small chunks at a time calling new and/or malloc/calloc etc? This was just an idea, so if it is really stupid, please be gentle Thanks, EvillivE
Evillive2
DerekSaw
DerekSaw
IMO, by grabbing (and releasing) memories of small chunk many times could have mem fragmentation, which might have unexpected worst case scenario (excessive page swapping). You should know that already.

If you do it by grabbing such large chunk, you reduce the overhead of many OS allocation calls. However, do have in mind that you need to implement a seperate memory management libraries... another overhead to ponder around. Unless it yields a significant advantages over your code, then no harm on doing it.
"after many years of singularity, i'm still searching n the event horizon" o
evillive2
evillive2
Thanks for the reply,

Yeah, I understand that by grabbing memory in many small doses may/will cause memory fragmentation, and that I will have to manage the memory myself if I choose to use the big chunk. However, is memory fragmentation really a big problem? Back to the original question, what I was wondering basicly was is it worth writing my own memory management utilities? Does calling new or malloc really cause that much of a hit where there is a noticeable difference? or are we talking like 1/100th of a frame per second here if I squeeze all I can out of doing it myself?

like if I did something like this:


  
// pointer to the beginning of the memory block

void *memory_block = calloc( 1, MAX_MEMORY_SIZE );

// pointer to the current location in the memory block

void *position = memory_block;

// pointer to "a" list of recycled pointers

// for this data type

SOME_DATA_TYPE *sdt_free_list = NULL;

void *alloc_new( size_t mem_needed )
{
void *pMem;

pMem = position;
position += mem_needed+1;

return pMem;
}

SOME_DATA_TYPE *new_some_data()
{
SOME_DATA_TYPE *psdt;

if ( sdt_free_list )
{
psdt = sdt_free_list;
sdt_free_list = sdt_free_list->next;
return psdt;
}

psdt = (SOME_DATA_TYPE*)alloc_new( sizeof(*psdt) );
return psdt;
}

void recycle_sdt( SOME_DATA_TYPE *psdt )
{
// do some stuff here to remove it from any linked

// list it might be in and zero out the memory

//...... blah blah


// now add it to the free list

psdt->next = sdt_free_list;
sdt_free_list = psdt;

return;
}

// somewhere

SOME_DATA_TYPE *pUgh = new_some_data();

...
...

// somewhere else

recycle_sdt( pUgh );


Now I realize I would have to do something like new_some_data and recycle_sdt for every type of object to use the memory block, or with some effort get it so alloc_new and recycle_mem could be used instead of malloc/free respectively, but would I get any kind of benefit from doing so or would I just be writing a lot of needless code and wasting my time?

Evillive2
Xiol
Xiol
This is really one of those cases where you will have to try both, profile, and then see which one is faster.

You can try and work it out on paper, but the end result will rely on how the OS handles memory. So, can you do better? Modern OSs are pretty good at managing their memory.

But they are of course optimized for the general case. If your program has a very specific, and common use for memory allocation, then you can benifit from a custom memory manager.

So if you have a special case, such as allocating/deallocating many similar or same sized chunks of memory, you could be better off doing so. Like if you are frequently creating/deleting polygons, then a specialized memory manager could provide a lot of speed over the standard memory manager, because you could avoid expensive alloc/free calls.

However if your program is more generalized and varied in its memory use, the OS management is probably going to be better.

You might be better off with a hybrid, use a specialized (and low-overhead) memory manager for one task, and use malloc/free for other allocations.
x-bishop
x-bishop
personally, i would not do this as the OS would handle memory management than you ever possibly could (no offence)

unless your running DOS or something, modern OS are multiprogramming systems, meaning they store multiple programs and the fundamental task of memory management is to ensure effective and safe execution of programs by fairly sharing memory and providing memory protection between concurrently resident processes

now by calling malloc, all youd be doing is heap management, all the object code/static data/and stack will still be handled by the OS transparently.

you wont be explicity accessing memory locations since i assume your going to be doing this in a purely HLL like C++, and not be messing around with the code generated ASM instructions in the debugger

so i doubt youll be comprimising other processes.

anywhoo the moral of the store is that your compiler/linker/loader as well as your OS will do the job for you

plus no one really does any significan memory management explicitly unless their working with embedded systems where memory is hard to come by, like PDAs or what have you.

if anyone disagrees with me, please feel free to correct me

im just going by what i''ve learned in my Operating Systems class, and that was awhile ago (year ago)...and i havent done any real low level systems programming since then
evillive2
evillive2
Thanks everyone, your input is very much appreciated

On a side note, DerekSaw mentioned memory fragmentation earlier... How much of a drawback is that if at all? I don't recall ever worrying that the memory I used wasn't linear, I just assumed it wasn't a big deal. Am I wrong?

[edited by - evillive2 on January 17, 2003 2:30:42 AM]
Evillive2
DerekSaw
DerekSaw
quote:
Original post by evillive2
On a side note, DerekSaw mentioned memory fragmentation earlier... How much of a drawback is that if at all? I don't recall ever worrying that the memory I used wasn't linear, I just assumed it wasn't a big deal. Am I wrong?


Let's make some rough guess (and assumption) here. Suppose the OS partition the memory as a page with size of 4096 bytes (4kb) large. Therefore the virtual memory page size should be 4kb (i assume).

Now let's say you have a link list. And the link list you are having are storing each node in a seperate page individually (caused by some various type of alloc/dealloc ). Thus traversing from begin 'til end requires you to walk through each pages.

If so coincidently that the OS have so limited memory left, it will do rigorous swapping. The OS might swap to disk 'currently' not used pages, and swap back to RAM for the specific page you are 'currently' accessing. Because the nature of your link list, each traversing from one node to the next will result a page swap... you should experienced b4 page swapping is damn slow.

[EDIT] btw, since memory allocation usually look for the chunk that is big enough (best fit?) plus fragmentation happens to create many tiny chunks. Therefore the OS might have no choice but to allocate a new page of memory just for your chunk.

[EDIT2] Correct me if I'm wrong. This is what I assumed... since I haven't face this kind of worse case before.

[edited by - DerekSaw on January 17, 2003 3:07:20 AM]

[edited by - DerekSaw on January 17, 2003 3:09:45 AM]
"after many years of singularity, i'm still searching n the event horizon" o
IFooBar
IFooBar
what you could do is use the normal new/delete functions for general memory allocations, like for allocation new memory for your graphics renderer, cause you''ll have just one of those. But suppose you''ll be managing a huge amount a polygons, and new/deleting ''ing a few every frame. For that kind of situation you can make a class that recycles memory. something like what you have. You can make it a template class and give it a size, so that it allocates that memory upfront, and then your polygones dont have to new/delete every frame, instead you just request any fre memory from the memory recycler.

also maybe you can have the memory recycler store the data in an array or something. So that accessing individual pieces of memory becomes a snap. for example say you know that you are going to have 1000 polygons max. you would assign the memory up-front using a memory recycler, and just request individual pieces of that recycler when needed.

You can also use flags to mark the array elemts used or unused, and. have new/delete functions for that class so it would look like something like this


  
cMemoryRecycler<PolStruct> polies( 1000 );
for( int i = 0; i < 1000; i ++ )
{
PolyStruct* ps = polies.GetNew();
ps->x = blah;
}

Of course ovelroading the new/delete operators would make it look really nice


:::Al:::
[Triple Buffer V2.0] - Resource leak imminent. Memory status: Fragile
[size=2]aliak.net
joanusdmentia
joanusdmentia
well, at a slightly educated guess, if you are just allocating a lot of small chunks then that should be fine, the fragmentation problem lies in the constant allocation/deallocation of those small chunks. If that's what you'll be expecting to do then look into memory pooling, which is the pretty much the same as what your thinking of but keeping each allocation block in each pool a constant size and typically the same type of object, for example in a particle system that constantly has particles being created and destroyed, the particles would be allocated/deallocated from a memory pool.

[edit]
memory pool...memory recycler...same diff
[/edit]

Joanus D'Mentia
---------------
The three phases of me...
The twit, the tool and the lonely fool.

[edited by - joanusdmentia on January 17, 2003 4:24:18 AM]
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The nly verdict is vengeance; a vendett o

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.