🔒 Locked
memory management
Advertisement
Original Post
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
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.
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.
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:
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?
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?
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.
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.
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
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
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]
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]
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
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]
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
Of course ovelroading the new/delete operators would make it look really nice
:::Al:::
[Triple Buffer V2.0] - Resource leak imminent. Memory status: Fragile
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
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]
[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]
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement