PDA

Voir la version complète : [GBA][Aide] RAM/IWRAM et taille mémoire


Dr.Vince
14/05/2006, 16h50
Bonjour amis codeurs,

voilà j'ai 2/3 questions sur la RAM de notre bonne vieille GBA :

- j'aimerais savoir s'il y a un moyen de connaitre la RAM utilisée sur GBA car en ce moment je fait mumuse avec les pointeurs et j'aurais voulu être sur que je libère correctement la RAM

- autre question : quelle est la taille de la RAM sur GBA

- et encore une aute question: quand on met du code en IWRAM quelle est la place occupé par le code, c'est à dire si on utilise une liste chaine dans du code en IWRAM, y a juste le code en IWRAM ou également les données, c'est à dire la liste chainée car du coup celle-ci serait alors limité par la taille de l'IWRAM


Merci pour vos réponses !!!

Brunni
14/05/2006, 17h08
Avec le linkerscript de HAM (que tu utilises HAMLib ou pas), tu peux utiliser les symboles __iheap_start et __eheap_start, ça te permettront de connaître la mémoire interne utilisée par ton programme (à la compilation, ça ne compte pas ce que tu fais après, comme les malloc, la pile, etc.).
Exemple:
L'IWRAM est à 0x3000000, si _iheap_start est à 0x3005000, ça veut dire que tu utilises 20 ko d'IWRAM avec les variables globales & fonctions en IWRAM. Par contre ça ne compte pas la taille utilisée par les variables locales, pour ça il faut vérifier le registre sp au niveau le plus haut de ton prog (c'est-à-dire le plus d'imbrications avec le plus de variables... difficile à déterminer). Plus sp est bas, plus tu utilises de pile, donc moins d'IWRAM est dispo.
Si sp est une fois inférieur à 0x3005000 (dans notre cas), là ton programme plantera. Donc en fait il est très difficile de déterminer la réelle utilisation d'IWRAM.
Pour l'EWRAM c'est pareil, si _eheap_start est à 0x2010000 ça veut dire que tu utilises 64 ko de mémoire, donc que 192 sont dispo pour les malloc et cie. Maintenant pas de moyen simple pour savoir l'utilisation en comptant les malloc, bien sûr... :(
Le mieux c'est de générer une 'linker map' avec ton programme, ça te permettra de voir quels symboles utilisent quelle mémoire et en quelle quantité, et ainsi de traquer par exemple un tableau qui gaspille de l'IWRAM parce que t'as oublié 'const'... ;)
Pour la taille c'est 256 ko pour l'EWRAM et 32 ko pour l'IWRAM. Pour les données de la liste, si tu les alloues dynamiquement (malloc) elles seront en EWRAM, donc avec 256 ko tu as de quoi faire ^^
Sinon il faut spécifier que ton tableau doit être mis en EWRAM (et ça ça dépend de ton compilo).

Lestat
14/05/2006, 19h12
Dr.Vince, récupère toi le gba cribsheet sur le site d'alekmaul

http://www.portabledev.com/pages/gba/tutoriels/gba-cribsheet.php

tout y est ;)

Dr.Vince
14/05/2006, 21h15
merci pour le lien Lestat.

sinon Brunni, si j'ai bien compris ce que tu me dis, y a juste le code de la fonction qui est mis en IWRAM, les variables seront mises en EWRAM, c'est ça ???

et sinon effectivement je fais beaucoup de dynamique, donc c'est mort mais je testerais quand même ce que tu as dit juste pour voir la mémoire dont je dispose.

Merci

Nesgba
22/05/2006, 09h38
marran ca j'ai commencé a gerer mes sprites par liste chainée il n'y a pas tres longtemp et le seul moyen que j'ai trouvé pour voir si je libere bien de la memoire c'est d'en créer beaucoup en virer et ainsi de suite une centaine de fois d'affilé a differantes etapes de ton programme le mieu est de tout placer en iwram pour les tests comme ca si tu efface pas bien tes structures (free() powa) tu deborde de l'iwram et tu plante ton prog direct alors que avec l'ewram c'est plus difficile a voir.

sinon une fois que ca marche correctement c'est la structure+variables de tes sprites que tu met en ewram la fonction qui parcour/cree/efface tes listes tu peut la mettre en iwram (vaut mieu)

Brunni
22/05/2006, 09h47
Dr.Vince> En général, mieux vaut éviter l'allocation dynamique dans un jeu, c'est très lent parfois et ça risque de te bloquer si tu veux exploiter à fond la GBA ;)
Et non, toutes les variables (avec HAM du moins) sont en IWRAM par défaut. Les variables locales sont sur la pile, c'est-à-dire en IWRAM aussi.
Les fonctions et les données 'const' sont en ROM (ou en EWRAM si tu as activé le MULTIBOOT) par défaut.

Nesgba
22/05/2006, 10h16
Dr.Vince> En général, mieux vaut éviter l'allocation dynamique dans un jeu, c'est très lent parfois et ça risque de te bloquer si tu veux exploiter à fond la GBA ;)
ca depend de ce que tu en fait, si tu utilise des listes chainés sur des sprites que tu cree et efface tres regulierement tu va perdre pas mal de temp a parcourir tes listes, mais si tu les utilises occasionelement tu va gagner de la place en rom surtout si tu as des structures de sprites gigantesques (j'ai pris l'exemple des sprites pour que ce soit comprehensible mais ca pourrai etre autre chose)

Dr.Vince
22/05/2006, 12h22
bah je suis obligé d'utiliser des listes chainées car c'est pour faire un algo d'IA, donc du dynamique dans tout les sens

sinon c'est abusé ça si HAM met toutes les variables en IWRAM :huh:

et autre petite question à la con, j'ai subitement un doute là, quand tu as une structure_1 qui contient un membre qui est un pointeur sur une autre structure_2
Tu fabrique une liste de structure_1, mais quand tu fait ton free() tu libère juste le pointeur sur structure_1 ou alors faut aussi libérer le pointeur sur structure_2 ??

Nesgba
22/05/2006, 13h14
bah je suis obligé d'utiliser des listes chainées car c'est pour faire un algo d'IA, donc du dynamique dans tout les sens

sinon c'est abusé ça si HAM met toutes les variables en IWRAM :huh:

et autre petite question à la con, j'ai subitement un doute là, quand tu as une structure_1 qui contient un membre qui est un pointeur sur une autre structure_2
Tu fabrique une liste de structure_1, mais quand tu fait ton free() tu libère juste le pointeur sur structure_1 ou alors faut aussi libérer le pointeur sur structure_2 ??

il me semble que liberer la structure 1 suffi, a confirmer.

ham ou pas ham toutes les variables > iwram a moin que tu specifie de les mettres en ewram
mais par exemple lorsque tu crée une structure

typedef struct S_Strucalacon
{
u8 jesuispetit ;
u16 *jepointe ;
s32 jesuisgrand ;
float evitezdemutiliser ;
} S_Strucalacon ;

extern S_Strucalacon __attribute__ ((section(".ewram"))) MaStructure[10] ;

tu n'a pas besoin de specifier ou vont tes variables puisque qu'elle font partie de ta structure que tu met elle meme en ewram (si tu ne met rien elle va en iwram aussi)

/!\ ne fonctionne que en dehors d'une fonction /!\

variable en iwram
int var1 ; revien a ecrire int __attribute__ (section(".iwram")) var1 ;

variable stockée en ewram
int __attribute__ ((section(".ewram"))) var1 ;

Nrx
22/05/2006, 22h50
bah je suis obligé d'utiliser des listes chainées car c'est pour faire un algo d'IA, donc du dynamique dans tout les sens
Ca depend de ce que tu veux faire... Tu peux envisager de reserver un tableau suffisamment grand si tu connais la taille max de ta liste. C'est ce que je fais dans mon pathfinder : j'evite autant que faire se peut d'allouer dynamiquement.

et autre petite question à la con, j'ai subitement un doute là, quand tu as une structure_1 qui contient un membre qui est un pointeur sur une autre structure_2
Tu fabrique une liste de structure_1, mais quand tu fait ton free() tu libère juste le pointeur sur structure_1 ou alors faut aussi libérer le pointeur sur structure_2 ??
J'ai peut-etre mal compris ce que tu expliques, mais ma reponse est : oui, il faut d'abord liberer ta structure_2 avant de liberer ta structure_1 (dans la mesure ou structure_1 contient un pointeur sur structure_2, pas directement une instance de cette structure). D'ailleurs tu as normalement fait un malloc pour structure_2... et il faut autant de free que de malloc ! Note bien que personne d'autre que toi peut savoir s'il faut liberer structure_2 quand on detruit structure_1 ; tu pourrais tres bien avoir besoin de conserver cette structure_2 pour l'utiliser autre part !

Dr.Vince
22/05/2006, 23h47
nan c'est mort pour le tableau de grande taille, c'est pas pour du pathfinder mais pour du minmax, avec un nombre de possiblité trop variable (càd que je connais pas à l'avance le nombre de branche pour chaque noeud)

sinon tu as bien compris pour les structures, c'est bien ce que je me disais faut libérer la structure_2

Nrx
23/05/2006, 00h46
nan c'est mort pour le tableau de grande taille, c'est pas pour du pathfinder mais pour du minmax
Tu fais un jeu de reflexion ? J'ai code un alpha-beta pour un Othello (sur PC), et je n'ai pas un seul malloc dedans : comme la fonction de recherche est recursive, je stocke betement tout sur la pile => pas besoin d'allocation/liberation memoire :).

Pour la petite histoire, j'avais commence a faire un portage sur GBA il y a 2 ans... mais ma "petite demo sans pretention (http://www.playeradvance.org/old/index.php?showtopic=6493)" a finalement pris le dessus.
Si mon Othello t'interesse : L'executable DOS est ici (http://www.artplastique.free.fr/nrx/PC/Nrx_oth/NRX_OTH.EXE) (3216 octets* !!) ;
Le source est la (http://www.artplastique.free.fr/nrx/PC/Nrx_oth/NRX_OTH.ASM).

*Oui, je suis tres fier de mon "micro" Othello, et je vous mets au defi de le battre aux niveaux 3+ !! (la honte si vous vous faites battre par un programme de moins de 4 Ko :whst:)

p.s. : Les touches a utiliser sont [fleches haut/bas/gauche/droite], [espace], et [echap].

Tembargo
23/05/2006, 00h48
En passant Refix va commencer un reversi (= othello) sur ds, ça pourrait l'intéresser si Dr.Vince n'est pas prenneur :)

Dr.Vince
23/05/2006, 12h10
pour l'algo alpha-beta je comptais le développer après pour comparer les perfs, même si c'est tout vu d'avance


sinon je suis obligé de faire des malloc pour gérer les listes de noeud ouverts et fermés car j'en ai un nombre non prévisilbe à chaque fois (enfin je connais le max quand même), mais je vais regarder dans ta source pour voir

et sinon non merci pour Othello, j'ai déjà bien trop de chose à faire !!

[EDIT] bouououhhhhh, c'est de l'ASM tes sources !!! j'y pige rien, c'est pas grave

Nrx
25/05/2006, 14h06
[EDIT] bouououhhhhh, c'est de l'ASM tes sources !!! j'y pige rien, c'est pas grave
Ah oui, c'est de l'assembleur, mais le x86 n'est pas très compliqué (évidemment il faut s'y mettre, mais bon...). Enfin bref, comme je le disais, l'idée dans mon Othello est d'utiliser la pile pour stocker les informations, afin d'éviter de devoir allouer/libérer la mémoire : à chaque noeud le programme part en récursion (la fonction se rappelle elle-même), la pile est utilisée naturellement, grandissant toute seule selon la profondeur de recherche...

Note : Une autre astuce possible dans l'implémentation des jeux de réflexion à base d'Alpha-Beta est de limiter la mémoire utilisée en ne stockant pas toutes les infos, mais en se donnant les moyens de jouer "à l'envers" : au lieu de mémoriser le damier entier à chaque noeud, il est possible de n'utiliser qu'un damier en variable globale ; il faut juste s'assurer qu'à chaque fois qu'on joue un coup on sera capable de "jouer à l'envers", i.e. de remettre tout en ordre. Evidemment cela dépend du type de jeu réalisé - ce n'est pas toujours possible/facile... Par exemple pour un Puissance 4, inutile de mémoriser la grille de jeu à chaque noeud, tu peux tout bêtement jouer le coup dans une grille "globale", partir en récursion, et supprimer le coup joué quand tu remontes, ce qui est très simple dans le cas du Puissance 4.

Au fait, je viens de réaliser : c'est sur une IA de jeu de cartes (http://www.playeradvance.org/forum/showthread.php?t=2556) que tu bosses ??

Dr.Vince
25/05/2006, 14h59
nan ce n'est pas une IA de jeu de cartes :lol:

sinon pour l'optimisation j'avais déjà opté pour cette solution car sinon j'allais exploser la mémoire je pense.

là j'ai pas trop le temps de m'y mettre car je bosse sur PA Card Games, mais peut-être je reviendrais avec d'autres questions

Nesgba
25/05/2006, 15h17
tien j'ai pas bien compris l'histoire de tes 2 structures alors :S un bout de code peut etre :rolleyes:

Dr.Vince
25/05/2006, 19h39
bah en reprenant ton exemple tu as une liste de S_Strucalacon, donc faut-il libérer également jepointe si jepointe est un pointeur sur une autre structure ?