Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1474 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [OWNED] Definir l'adresse d'un tableau

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[OWNED] Definir l'adresse d'un tableau

n°949301
FonzieV
Posté le 08-01-2005 à 19:22:40  profilanswer
 

Hello,
Bon, je sais que c cho à expliquer mais  :D ...
 
 
Je bosse sur un jeu et je dois réaliser la chose suivante:
Sur emulateur, le tableau[] doit être placé en ram (peu importe l'adresse).
Sur console, le tableau[] doir être placé en rom (à une adresse précise).
Pour passer de l'un a l'autre, j'édite qu'une seule ligne de code (et pas toutes les fois où est utilisé le tableau).
 
Donc, dans tout mon programme j'utilise (truc dans le genre):
unsigned char map_data[256]; //Création d'un tableau en ram, à une adresse *inconnue*.
...
map_data[x+y*32]=z;
 
Mais voila, comment faire pour que map_data soit placé a une adresse bien précise??!
 
J'ai pensé faire:
unsigned char *map_dat;
map_dat= (uchar*) 0x01100;
...
map_data[x+y*32]=z;
 
Mais, celà "bouffe" des instructions cpu supplémentaires à chaque utilisation du tableau (addition de deux adresses *variables*).
Alors que dans le premier exemple, le cpu additionne une valeur fixe à une valeur *variable*...
 
Donc, comment faire?
Il y a t'il un moyen du style (au hasard) : "#define address map_data 0x01100" ?
PS: J'utilise GCC (comme compilateur).
 
En GROS GROS GROS :
Je cherche à pouvoir controller l'adresse d'un tableau (qui est normalement crée en RAM, de façon incontrollable) AVANT compilation.
 
 
Merci de vos réponses.
 
A+
 
Fonzie


Message édité par FonzieV le 10-01-2005 à 15:40:35
mood
Publicité
Posté le 08-01-2005 à 19:22:40  profilanswer
 

n°949329
Emmanuel D​elahaye
C is a sharp tool
Posté le 08-01-2005 à 21:23:32  profilanswer
 

FonzieV a écrit :

Hello,
Bon, je sais que c cho à expliquer mais  :D ...
 
Je bosse sur un jeu et je dois réaliser la chose suivante:
Sur emulateur, le tableau[] doit être placé en ram (peu importe l'adresse).
Sur console, le tableau[] doir être placé en rom (à une adresse précise).
Pour passer de l'un a l'autre, j'édite qu'une seule ligne de code (et pas toutes les fois où est utilisé le tableau).


/* global.c */
#include "global.h
 
/* definition externe : -DEMULATION ou rien */
#ifdef EMULATION
static unsigned char map_data_[MAP_DATA_SIZE];
unsigned char *map_data = map_data_;
#else
unsigned char *map_data = (unsigned char *)ADRESSE_EN_DUR;
#endif


On utilise partout 'map_data' comme un tableau
 

/* global.h */
#define MAP_DATA_SIZE 256
extern unsigned char *map_data;


Dans le linker de la cible réelle :
 
reserver 256 octets à partir de l'adresse ADRESSE_EN_DUR


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°949354
Taz
bisounours-codeur
Posté le 08-01-2005 à 22:19:29  profilanswer
 

vive les compound literals de C99

n°949397
FonzieV
Posté le 09-01-2005 à 00:25:17  profilanswer
 

"/* global.c */
#include "global.h
 
/* definition externe : -DEMULATION ou rien */
#ifdef EMULATION
static unsigned char map_data_[MAP_DATA_SIZE];
unsigned char *map_data = map_data_;
#else
unsigned char *map_data = (unsigned char *)ADRESSE_EN_DUR;
#endif "
 
I see...
Par contre, faut pas que je me plante car c'est ce tableau la clef du "game engine" (au niveau de l'optimisation, c'est super hot)...
 
Donc tu me confirme que, au niveaux des instructions que ça va générer en asm, que :
j=tableauclassique[i];
est aussi rapide que (avec map_data comme tu l'as défini):
j=map_data[i];
?
 
Merci bcp.
-------------------------------------
Sinon, g testé le "tips":
 
static uchar dynamic_map[64*64*4];
uchar *ref_dynamic_map=dynamic_map;
 
ensuite, j'ai ça (dans les autres pages ou j'utilise le tableau)
extern uchar *ref_dynamic_map[];  
 
et quand je fait ref_dynamic_map[quelquechose]
j'obtient ça:
Error : "array subscript is not an integer"
bref, c zarb.
 
 
 
 
A+
 
Fonzie


Message édité par FonzieV le 09-01-2005 à 00:48:59
n°949431
matafan
Posté le 09-01-2005 à 16:55:28  profilanswer
 

Si tu déclares ton tableau avec "uchar *ref_dynamic_map" d'un coté, faut pas le déclater avec "extern uchar *ref_dynamic_map[]" de l'autre... Enlève les [].

n°949664
FonzieV
Posté le 09-01-2005 à 23:03:15  profilanswer
 

Merci bcp, ça marche nickel.
;) Bon et puis pour l'histoire de l'optimisation je laisse tomber, le 68K @ 8Mhz, c de la balle !

n°949797
lsdYoYo
gravity powered
Posté le 10-01-2005 à 10:08:54  profilanswer
 

Je te confirme que l'accès aux éléments de ton tableau est aussi rapide pour les deux manières de le déclarer :
- unsigned char tab[N];
- unsigned char *tab;
Le compilateur va, dans les deux cas effectuer les mêmes opérations lors des accès. En fait, en dehors de l'allocation de mémoire, les deux écritures sont "équivalentes", la seule chose que tu ne peux pas faire avec un tableau c'est déplacer son adresse de départ (unsigned char tab[N]; ..... tab++). Du reste, si tu lui affectes une valeur dès la déclaration, ce serait une bonne idée de déclarer ton pointeur avec "const" : unsigned char * const tab = ADRESS;
Au cas où tu en aurais besoin, voici les 2 écritures pour un tableau à 2 dimensions :
- unsigned char tab[N][10];
- unsigned char (*tab)[10];  //() pour priorité entre * et []

n°950077
FonzieV
Posté le 10-01-2005 à 15:13:35  profilanswer
 

Ok, merci à tous.
lsdyoyo, c exactement la réponse que j'attendais quand je parlais des cycles cpus, en plus avec "const", c encore plus classe (il faut souvent ajouter ce genre d'infos quand on compile au niveau maximum d'optimisation avec GCC, cf : "volatile" ).
 
Pour les tableaux a 2 dims, c bon a savoir mais je préfere controller toutes les multiplications moi-même (pour pouvoir faire des << et >> à la place)... Enfin, je me comprends LOL.
 
Merci bcp.
 
++
 
Fonzie

n°950623
lsdYoYo
gravity powered
Posté le 11-01-2005 à 11:46:40  profilanswer
 

Deux remarques :
- const me modifie en rien le code généré (contrairement à "volatile" ). Ca permet d'obtenir des erreurs à la compilation si le source veut modifier une variable "const".
- A moins que tu ne descendes jusqu'au niveau de l'assembleur, les compilos s'en sortent bien souvent mieux que toi pour optimiser les accès aux structures ou tableaux. Il existe, notamment sur processeur Intel, des modes d'adressages spécialisés pour les tableaux d'éléments de taille 2, 4 et 8. Je pense aussi que la majorité des compilos sont suffisamment optimisés pour employer un décalage de bits plutôt qu'une multiplication si la variable est "unsigned". Dans un source, "x * 32" est plus lisible que "x << 5".

n°950630
fafounet
Posté le 11-01-2005 à 11:56:53  profilanswer
 

En parlant d'optimisation, y'a pas moyen d'optimiser lorsque l'on parcourt un tableau à deux dimensions par les colonnes ?? (pour que le cache serve à qqchose)


Message édité par fafounet le 11-01-2005 à 11:57:29
mood
Publicité
Posté le 11-01-2005 à 11:56:53  profilanswer
 

n°950719
Emmanuel D​elahaye
C is a sharp tool
Posté le 11-01-2005 à 13:47:10  profilanswer
 

lsdyoyo a écrit :

Deux remarques :
- const me modifie en rien le code généré (contrairement à "volatile" ). Ca permet d'obtenir des erreurs à la compilation si le source veut modifier une variable "const".


Ca dépend, de l'implémentation, mais 'const' peut avoir une influence importante sur la taille du code généré et l'empreinte mémoire.  
 
Par exemple :  

static int a[] = {1, 2, 3, 4};


génère  

  • Une réservation mémoire (RAM) de 4 int
  • Une zone d'initialisation dans le code (PROM, Flash, RAM en lecture seule) de 4 int.


[format Motorola, int 32-bit]

00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04


  • un code de recopie de cette zone dans la zone mémoire au démarrage.


alors que

static const int a[] = {1, 2, 3, 4};


génère :  

  • Une zone d'initialisation dans le code de 4 int

et c'est tout.
 
En embarqué, ça peut avoir son importance...


Message édité par Emmanuel Delahaye le 11-01-2005 à 13:50:40

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°950848
Taz
bisounours-codeur
Posté le 11-01-2005 à 15:55:14  profilanswer
 

pas qu'en embarqué.

n°950854
lsdYoYo
gravity powered
Posté le 11-01-2005 à 15:57:45  profilanswer
 

Emmanuel Delahaye a écrit :

static int a[] = {1, 2, 3, 4};

génère  

  • Une réservation mémoire (RAM) de 4 int
  • Une zone d'initialisation dans le code (PROM, Flash, RAM en lecture seule) de 4 int.
  • un code de recopie de cette zone dans la zone mémoire au démarrage.

Je suis surpris. Tu es sûr qu'un compilo va générer ET une allocation fixe ET un code de recopie alors que le tableau est déclaré en "static" ?!
Pour un tableau local (auto) du style "int a[] = { 1, 2 };" ok, mais en "static"... Et comment ça se passe en global, le compilo génère N appels à N recopies de bloc avant l'appel de main() ? Hummm... c'est lourd et je ne vois pas l'intérêt.


Message édité par lsdYoYo le 11-01-2005 à 15:59:02
n°950986
Emmanuel D​elahaye
C is a sharp tool
Posté le 11-01-2005 à 17:41:36  profilanswer
 

lsdyoyo a écrit :

Je suis surpris. Tu es sûr qu'un compilo va générer ET une allocation fixe ET un code de recopie alors que le tableau est déclaré en "static" ?!
Pour un tableau local (auto) du style "int a[] = { 1, 2 };" ok, mais en "static"... Et comment ça se passe en global, le compilo génère N appels à N recopies de bloc avant l'appel de main() ? Hummm... c'est lourd et je ne vois pas l'intérêt.


J'ai constaté ça sur plusieurs plateformes embarquées (Mentor Graphics ex-MRI, notamment).
Comme je l'ai dit, ça dépend de l'implémentation. Je préfère écrire du code qui sera optimisé au mieux.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°951158
FonzieV
Posté le 11-01-2005 à 21:08:55  profilanswer
 

"Je suis surpris. Tu es sûr qu'un compilo va générer ET une allocation fixe ET un code de recopie alors que le tableau est déclaré en "static" ?!"
Oui c'est logique de toute façon.
 
"En embarqué, ça peut avoir son importance..."
Effectivement, j'ai 64Ko de workram et 256ko de program ram.
Donc ça fait une sacré dif d'avoir un tableau de 32Ko "en double".
 
 
Btw: j'utilise "volatile" comme une sorte d'information pour le compilateur.
Je travail avec des fifo's et gcc n'aime pas trop les écritures multiples genre "for(i=0;i<300;i++){*pw=56;}", il a tendance à supprimer des bout de code pour optimiser si on ne précise pas "volatile" pour les pointeurs de la fifo.


Message édité par FonzieV le 11-01-2005 à 21:09:53
n°951251
matafan
Posté le 11-01-2005 à 22:49:11  profilanswer
 

Tu dois preciser volatile parce que tes pointeurs sont volatiles. Si ton pointeur n'est pas modifie de maniere asynchrone (par un autre thread par exemple), pas besoin de volatile.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [OWNED] Definir l'adresse d'un tableau

 

Sujets relatifs
Jte défi de remplir un tableau!Modifier l'adresse de la barre
CSS vs layout tableautableau triable en ligne
tableau triable en lignebouton à positionner dans tableau
[C] Tableau dynamiqueintégrer un tableau
Enregistrer dans un fichier un tableau de structureTableau a double entrée
Plus de sujets relatifs à : [OWNED] Definir l'adresse d'un tableau


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR