#117893 - KayH - Thu Feb 08, 2007 12:59 pm
Hi,
in http://forum.gbadev.org/viewtopic.php?t=12356 wintermute wrote:
Quote: |
malloc adds around 32k iirc |
I need malloc some times to create elements of a list. Each element has a size of about 32Bytes.
sprintf waste about 20k ... :-(
Because of this I wrote my own "print" method, before I found the posprint. :-)
For the malloc, is there any chance to decrease the used space or any other method to use (except from a selfmade mem manager written in asm...)? For me it seems it would be better then to use a (global) array instead of a list (as long as I haven't wrote my own mem manager).
sgeos:
Quote: |
I have an HSB library for the GBA. Do you want it? |
What is a HSB library?
(As this was written some posts above the current, I do not want to interrupt the current discussion there and open this new thread. I hope this is ok for you.)
best regards
KaY
#117903 - Miked0801 - Thu Feb 08, 2007 4:32 pm
No need to write an ASM manager. Think of malloc as a memory chunk assigner. Each chunk is a linked list pointing to the next chunk. Have a free list header and a used list header. Create a free list chunk that encompasses the entire amount of free ram (minus your LL header.) Every time a malloc occurs, go grab a chunk off the free list and "split" it to the size you need (or better, search the whole list for the closest size that will fill your need). When free is called, check the chunk around it to see if you can "join" them back together.
This basic malloc idea can be coded in straight C and will work for most uses. It will fragment if you aren't careful, but that can be managed be careful ordering of your mallocs and frees.
#117915 - tepples - Thu Feb 08, 2007 6:03 pm
KayH wrote: |
sprintf waste about 20k ... :-( |
siprintf() wastes less space, and it does everything sprintf() does except floats and doubles.
Quote: |
For the malloc, is there any chance to decrease the used space or any other method to use (except from a selfmade mem manager written in asm...)? For me it seems it would be better then to use a (global) array instead of a list (as long as I haven't wrote my own mem manager). |
"List" is an interface. A list can be implemented with an array, a singly linked list, or a doubly linked list. ArrayList makes the array bigger every time the list grows by a factor of 1.5.
Quote: |
sgeos:
Quote: | I have an HSB library for the GBA. Do you want it? |
What is a HSB library? |
Hue saturation brightness?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#117928 - sgeos - Thu Feb 08, 2007 7:24 pm
tepples wrote: |
Quote: | sgeos:
Quote: | I have an HSB library for the GBA. Do you want it? |
What is a HSB library? |
Hue saturation brightness? |
Hue saturation brightness. The effective range of each are as follows:
Code: |
Hue 0x00 ~ 0xBF
Sat 0x00 ~ 0x1F
Bri 0x00 ~ 0x1F |
EDIT: The background in the moon demo on the GBAccelerometer page uses this library, if you want to see a hue rotation.
-Brendan
#117929 - KayH - Thu Feb 08, 2007 7:57 pm
Thank you all, for your helpfull answers!
Miked0801:
OK, I'll keep this in mind, when I try to implement a mem manager. This seems to be a little bit related to some other tasks I've done so far. Using C will hopefully speed up this work. If I've trouble, I know who to ask. ;-)
Tepples:
When I wrote list, I mean my own implementation of a double linked list. (Probably you cannot remember one of my last comments in the forum, regarding a chess playing game. ;-) Here I need this kind of list on several places. BTW hopefully I will have a version I can show the community in the next time.)
I wasn't aware of the siprintf() ... But now I have a method which work as expected. When I clean up the code I will give this and also the posprint a try.
sgeos:
Thanks for clarification.
#117935 - gauauu - Thu Feb 08, 2007 9:02 pm
Speaking of writing my own memory manager....
It seems like for gba games, where you know the system and you know the exact limits of your games, instead of having a general memory pool to draw from, that it could be more efficient to have multiple memory pools for all your object types.
For example, in my game, I know that there will never be more than 50 bullets, 1 main character, and 20 enemies at once. So I just create global arrays for bullets[50], enemies[20], etc. Then write some functions to properly hand out that memory when I want to instantiate an object, and recycle it once the object is done.
Is this a bad idea, in any way? It seems easy to manage, and fast. But maybe I'm missing something?
#117940 - sgeos - Thu Feb 08, 2007 9:37 pm
Seems fine to me. Your functions should be able to handle an arbitrarily large number of objects, but I don't see anything wrong with statically allocating a maximum number of objects by design. Once you allocate a buffer, you don't have to use all of it (different numbers of objects per area).
-Brendan
#117948 - Miked0801 - Thu Feb 08, 2007 10:18 pm
That's also how we do it when possible. Either alloc them at runtime via arrays or Malloc them if we want them on the Heap instead. This also reduces memory frag issues.
#118906 - KayH - Sun Feb 18, 2007 4:04 am
Thanks!
I created a global array of a certain amount of members. Additionally I have a get and a free method to deliver the space to use and free them when it is unused.
I have two questions more:
1) I used malloc also to get the remaining free space. This isn't possible anymore, as I do not want to use malloc further. Is there a possibility to get the remaining memory?
2) Is there a limit for the stack? (like the AFAIK 1MB for windows on PC's) Of course the RAM himself is limited, but is there another limit?
#118930 - Ant6n - Sun Feb 18, 2007 9:08 am
1) use (void*)__eheap_start (refer to http://forum.gbadev.org/viewtopic.php?t=7088&highlight=heapstart)
2) stack usually sits at the end of internal ram (32K), and grows downward, but there might be data in in the internal ram; so the limitation is when data starts got overwritten, at most 32 K. If you need more there are ways to get around that.
When having to deal with many little elements, but not wanting all the overhead of malloc; i use some memory manager that for each chunksize that exists in the program (16,24 bytes etc) creates a big chunk (i.e. 1 KB) in which the chunks of the same size live as a linked list (only freed elements are linked, so that there is very little overhead). when I run out of memory in the big chunks, i just create another one.
#118952 - KayH - Sun Feb 18, 2007 3:54 pm
Many thanks!
1) I think I got it. This was a great help Ant6n.
2) How can I detect if the stack overwrite data/code placed in IWRAM? Is this automatically done by some startup code? Is this also checked at he reverse order somehow? I mean if I change some data which share the same place as the current stack(-position) (if possible), than the stack is corrupted and we get some results of this... (wrong data or jump adresses)
#118970 - tepples - Sun Feb 18, 2007 6:50 pm
In an emulator that supports breakpoints on writing to an address, you can set a write breakpoint on the words immediately after the end of the .bss section. (Check arm-eabi-nm -n mygame.elf to see where to set the breakpoint.) If code tries to write to that region, you know you have a stack overflow.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#118983 - Ant6n - Sun Feb 18, 2007 9:24 pm
the people that do the linking scripts for the devkitp should put some definition of __iwramheapstart or something like that
#119108 - poslundc - Mon Feb 19, 2007 7:56 pm
Also, your code will crash when you go execute it ;)
Dan.
#119168 - KayH - Tue Feb 20, 2007 12:35 pm
poslundc:
No, no, no, my program never crashs. This is a feature by design! *fg*
back to the serious:
in the map file there is a part:
Code: |
.ewram9 0x0202c608 0x0 load address 0x0201fe08
*(.ewram9)
0x0202c608 . = ALIGN (0x4)
0x0201fe08 __load_start_ewram9 = LOADADDR (.ewram9)
0x0201fe08 __load_stop_ewram9 = (LOADADDR (.ewram9) + SIZEOF (.ewram9))
0x0202c608 __ewram_overlay_end = .
0x0202c608 __eheap_start = .
0x0202c608 _end = .
0x0202c608 __end__ = _end
0x0202c608 PROVIDE (end, _end)
|
I assume __eheap_start is 0x0202c608, which gives about 80KB free memory on the heap?! Is this the meaning of
I also see (unfortunately) that the malloc is referenced on different locations in the mapfile and the size of the available memory was not increased. I had also about 80KB while I was using malloc in my own code. Therefore I think the malloc is used somewhere in the chain (libs)? Actually I use parts of the tonclib, although I do not need much of it. Could this be a reason for the malloc usage?