Page 1 of 1

Help with monitoring memory usage on Nintendo GameCube for Voxel Engine project

Posted: Fri Oct 11, 2024 2:25 pm
by Tebasvs

Hello everyone ^^

I'm currently working on a voxel engine for the Nintendo GameCube as part of my final year project. I'm using the native GX API and focusing heavily on memory optimization, given the system's limited 24MB of RAM. As my project revolves around optimizing performance and memory usage, it's crucial for me to have a reliable way to monitor how much memory is available and how much I've used during runtime.

I've been using malloc and calloc to dynamically allocate memory, and I'm trying to track memory usage by calling functions like SYS_GetArena1Hi() and SYS_GetArena1Lo() before and after allocations. However, I'm not seeing any changes in the reported memory, even though I am sure the allocations are happening.

Is there a better way in libOGC to track the actual memory usage, especially when using dynamic memory allocations? Or perhaps I'm missing a key detail about how memory management works on the GameCube? Any advice or alternative methods would be greatly appreciated, as memory optimization is a key part of my project!

Thanks in advance for your help!


Re: Help with monitoring memory usage on Nintendo GameCube for Voxel Engine project

Posted: Sat Oct 12, 2024 10:01 pm
by WinterMute

SYS_GetArena1Hi and SYS_GetArena1Lo are internal libogc functions which are used by sbrk internally to grab memory from the heap for newlib's malloc implementation. As memory is malloced and freed it will, for the most part, end up being managed by newlib itself although there are conditions which allow memory to be returned to the heap. Unfortunately there is no reliable way to monitor how much memory is available because some will still be on the heap, some will be allocated and some will be free but contained within newlib's management structures and what's available may not be available in a sufficiently large contiguous block to meet a given allocation.

What you can do is wrap malloc and free with your own functions to track allocations and build a picture of how much is allocated at any given point. When it comes to memory optimisation in games it's often better to make larger allocations and build your own dedicated pools from those which then provided fixed size blocks for particular purposes from lists of free objects. Hopefully that makes some sense.

To wrap malloc and free you can do something along these lines

Code: Select all

#include <stdint.h>
#include <stddef.h>
#include <malloc.h>

#include <ogc/system.h>

void *__real_malloc(size_t size);
void __real_free(void *ptr);


void *__wrap_malloc(size_t size)
{
   void *ptr = __real_malloc(size);
   SYS_Report("Allocating %d\n", malloc_usable_size(ptr));
   return ptr;
}

void __wrap_free(void *ptr)
{
   SYS_Report("Dellocating %d\n", malloc_usable_size(ptr));

   __real_free(ptr);
}

To have these functions used instead of malloc and free add -Wl,--wrap,malloc -Wl,--wrap,free to LDFLAGS for linking


Re: Help with monitoring memory usage on Nintendo GameCube for Voxel Engine project

Posted: Sat Oct 12, 2024 11:30 pm
by WinterMute

I should also have mentioned that the SYS_Report function I'm using here will output to Dolphin logs. See viewtopic.php?p=17727&hilit=SYS_Report#p17727