Bonjour,
Comment je peux initialiser une zone mémoire sans passer par la pile ?
J'ai essayé avec d'inliner ma fonctions mais passe toujours par la pile!!
Bonjour,
Comment je peux initialiser une zone mémoire sans passer par la pile ?
J'ai essayé avec d'inliner ma fonctions mais passe toujours par la pile!!
Bonjour,
Peux-tu préciser ta question s'il te plait? Donne nous un exemple appliqué si possible (Pourquoi tu veux faire ça exactement?).
Si tu veux que tes variables soient stockée dans les registres du micro processeur et non dans la pile tu peux utiliser le mot clé "register"
exemple :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part register short i, j;
Je déconseille d'utiliser register et encore plus de croire que la variable sera vraiment mise dans un registre ! Ce mot-clé est une simple indication pour le compilateur et ne donne aucune garantie. Le pourquoi est expliqué ici, au 3e paragraphe : http://c-faq.com/~scs/cclass/int/sx4ea.htmlEnvoyé par Neolex
Sans passer par la pile =Envoyé par Tilicht
1) ne pas du tout utiliser la pile (pour le stockage comme l'initialisation) ?
2) les variables ne sont pas stockées sur la pile ?
1) Ca veut dire que tu ne peux pas utiliser une fonction d'initialisation, donc il te reste les variables globales et statiques avec initialisation lors de la déclaration.
2) Tu peux utiliser les globales, les statiques, les allocations dynamiques et une fonction pour initialiser les valeurs.
l'idée est d'initialiser chaque bloc de données de 64 bit avec une valeur précise (surtout le bit 64 à 1), et sur une zone mémoire de 4 Ko par exemple.
voici la fonction que j'utilise:
avec cette fonction j'arrive à initialiser la zone mémoire, mais ça passe par la pile (pour chaque valeur de i et de l'adresse), donc des accès inutiles pour moi et ce qui prend du temps...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 inline void fct_null(uint32_t add, size_t size) { size_t i; volatile uint32_t *ptr; for(i=0;i<(size/8);i++) { ptr = (uint32_t*)(add + 0x4 + i*0x8); *ptr = 0x80000000; } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 inline void fct_null( uint64_t *add, unsigned long size/*nombre de 64 bits*/) { static unsigned long i = 0; for(i=0; i<size; i++) { *(add+i) = 0x8000000000000000; } }
Dernière modification par Invité ; 30/09/2014 à 20h29.
Merci Ratator! c'est vraiment ce que je veux.
Maintenant avec ton code l'initialisation passe plus vite.
Mais, il reste un petit problème, il n'y a plus d'accès à la pile pour la donnée ou pour l'adresse, par contre l'indice ' i ' de la boucle utilise toujours la pile!
Est ce qu'il y a un moyen de ne pas passer par la pile pour cet indice aussi?
@tilicht : au lieu de parler sans cesse du fait que tu ne veux pas passer par la pile, dis-nous plutôt ce que tu souhaites faire exactement et quel est le problème de ta solution actuelle.
Si ton problème est que ton code est lent et que tu penses que c'est à cause de l'utilisation de la pile, alors la réponse est "non, ce n'est pas la faute de la pile". Tu utilises volatile alors qu'il n'y en a absolument pas besoin et tu empêches ton compilateur de faire des optimisations sur la boucle, tuant les performances. Le code de Ratator est plus rapide aussi à cause de ça mais il a plusieurs probèmes : size_t est plus adapté que unsigned long (ce type est même fait pour cela) et le mot-clé static me donne envie de mettre des claques : il n'apporte rien, la fonction n'est plus réentrante et quasiment certains que cela grève encore les optimisations du compilateur.
Si tu ne veux pas utiliser la pile, alors n'utilise pas de fonction : une fonction utilise forcément la pile !!!!!!!Mais, il reste un petit problème, il n'y a plus d'accès à la pile pour la donnée ou pour l'adresse, par contre l'indice ' i ' de la boucle utilise toujours la pile!
Et puis comment sais-tu que i est sur la pile ? As-tu regardé l'assembleur pour voir s'il n'était pas mis dans un registre ?
Tu peux écrire ta propre fonction si tu as besoin de faire quelque chose de spéciale ou si les performances ne te conviennent pas, mais si tu souhaites remplir la mémoire avec une valeur particulière, pense à la fonction memset : http://linux.die.net/man/3/memset. Si c'est juste mettre le bit 64 (63 ?) à 1, tu remplis avec des 0xFFFFFFF et c'est fini. Sinon, une fonction comme ça devrait faire l'affaire :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 void f(uint64_t *p, size_t size) { const uint64_t * const pend = p + size; while(p < pend) { *p = 0x8000800080008000U; p++; } }
@Neolex : beaucoup n'y connaissent pas autant qu'ils ne le devraient ou sont encore bloqués dans les années 80 où register pouvait être utile.
Il y a peut-être une petite confusion sur ce qu'est une pile : si, en algorithmie, on t'explique qu'elle est d'exploitation plus lente qu'une mémoire à accès aléatoire (donc RAM), c'est parce qu'il faut la parcourir depuis son sommet pour accéder à l'élément concerné mais c'est vrai avec la plupart des structures de données, en particulier les listes chaînées.
Mais sur les machines habituelles, la pile n'est qu'un espace mémoire ordinaire exploité par un index, le pointeur de pile, stocké dans un registre du processeur. Ça veut dire que ta variable i se trouve exactement dans la même mémoire que celle que tu essaies d'initialiser et que le compilateur sait à l'avance à quelle distance elle se trouve du cadre de pile mis en place en entrant dans ta fonction. Donc accéder à i sera équivalent à accéder à ton tableau pointé par p.
Pas forcément, c'était vrai en soi et pendant longtemps, spécialement lorsque les machines étaient trop limitées en espace mémoire et en rapidité pour permettre au compilateur d'effectuer des heuristiques efficaces.
l'objectif est d'initialiser une zone mémoire le plus vite possible.
comment je sais qu'il y a des accès dans la pile! après la simulation j'ai remarqué qu'il y a deux types d'accès, dans la zone que je veux initialiser et la zone dédiée à la pile.
Je travaille sur une plateforme virtuelle de simulation (et pas sur ma machine)
voici un extrait de simul (en utlisant mon 1er code):
alors, l'add 0x7e000fxx c'est l'adresse de la pile et 0x9103xxxx c'est la zone que je veux initialiser.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 [CPU] add: 0x7e000f50-- cmd_data: 1 [CPU] add: 0x7e000f40-- cmd_data: 80000000 [CPU] add: 0x7e000f38-- cmd_data: 9103000c [CPU] add: 0x9103000c-- cmd_data: 80000000 [CPU] add: 0x7e000f50-- cmd_data: 2 [CPU] add: 0x7e000f40-- cmd_data: 80000000 [CPU] add: 0x7e000f38-- cmd_data: 91030014 [CPU] add: 0x91030014-- cmd_data: 80000000 [CPU] add: 0x7e000f50-- cmd_data: 3 ...
en utilisant le code de Ratator, j'obtiens:
avec ce code il y a moins d'accès à la pile et c plus rapide.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 [CPU] add: 0x7e000f40-- cmd_data: 0 [CPU] add: 0x91030004-- cmd_data: 80000000 [CPU] add: 0x7e000f58-- cmd_data: 1 [CPU] add: 0x9103000c-- cmd_data: 80000000 [CPU] add: 0x7e000f58-- cmd_data: 2 [CPU] add: 0x91030014-- cmd_data: 80000000 [CPU] add: 0x7e000f58-- cmd_data: 3 ...
avec ton code j'obtiens:
j'ai trouvé que les résultats de ton code est encore plus rapide.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 [CPU] add: 0x91030004-- cmd_data: 80000000 [CPU] add: 0x7e000f60-- cmd_data: 91030008 [CPU] add: 0x9103000c-- cmd_data: 80000000 [CPU] add: 0x7e000f60-- cmd_data: 91030010 [CPU] add: 0x91030014-- cmd_data: 80000000 [CPU] add: 0x7e000f60-- cmd_data: 91030018 ...
Mais le parfait pour moi c'est d'avoir:
Voila, j'espère maintenant que je suis plus clair!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 [CPU] add: 0x91030004-- cmd_data: 80000000 [CPU] add: 0x9103000c-- cmd_data: 80000000 [CPU] add: 0x91030014-- cmd_data: 80000000 [CPU] add: 0x9103001c-- cmd_data: 80000000 ...
Oui je suis d'acc avec toi, je l'ai modifié avant l'utiliser.Le code de Ratator est plus rapide aussi à cause de ça mais il a plusieurs probèmes : size_t est plus adapté que unsigned long (ce type est même fait pour cela) et le mot-clé static me donne envie de mettre des claques : il n'apporte rien, la fonction n'est plus réentrante et quasiment certains que cela grève encore les optimisations du compilateur.
Bonjour.
Je vais peut être dire une bêtise mais je me lance quand même .
J'ai un réflexe, peut-être stupide. Pour moi, si ce n'est pas dans la pile, c'est dans le tas. Ceci est peut être un abus de langage.
En partant de ce postulat (pour moi) j'allouerais toutes les variables dans le tas avec un joli malloc();.
N.B. : je n'ai pas testé ce code en l'état. C'est pour ainsi dire un pseudo-code...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 inline void fct_null( uint64_t *add, size_t size/*nombre de 64 bits*/) { size_t *i = malloc(sizeof(size_t)); for(*i=0; *i<size; *i++) { *(add+(*i)) = 0x8000000000000000; } }
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Ca devient plus clair tout çaEnvoyé par tilicht
Tu compiles comment ? Quel niveau d'optimisation ?
C'est quoi cette plateforme de simulation (pure curiosité personnelle) ?
Tu pourrais nous en dire un peu plus sur les valeurs après cmd_data ?Envoyé par tilicht
Les globales et les statiques ne sont ni dans l'un ni dans l'autre. Les constantes sont encore ailleurs.Envoyé par gerald3d
je travaille sur SoCLib: http://www.soclib.fr/
c'est une valeur en hexa, je mets le bit 32 à 1 du deuxième bloc de 32 bits (le 1er bloc de 32 bit je le touche pas, sinon c'est une écriture de plus vu que je compile sur un MIPS32, et donc j'utilise uint32_t et pas uint64_t )Tu pourrais nous en dire un peu plus sur les valeurs après cmd_data ?
est ce que je peux optimiser le code encore plus ?
Si ton bus de données est en 32 bits, ma fonction sera sans doute plus rapide avec des uint32_t qu'avec des uint64_t.
Bonjour
Tu ne t'es jamais dit que ce qui prenait le plus de temps c'était surtout le size/8 fait et refait à chaque itération ???
Peut-être essayer de gagner encore un peu en évitant le décalage "adr+i" à chaque itération...
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 inline void fct_null( uint64_t *add, unsigned long size/*nombre de 64 bits*/) { static unsigned long i; static uint64_t *pt; for(i=0, pt=add; i<size; i++, pt++) *pt = 0x8000000000000000; }
Bien tenté mais faudra regarder le coût du malloc(). Ceci dit, pense quand-même à libérer la mémoire allouée en fin de fonction au-moins pour éviter une superbe fuite mémoire...
Ils n'ont pas forcément eu la chance d'avoir un environnement de travail qui leur permette de se tenir à niveau...
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 inline void fct_null( uint64_t *add, unsigned long size/*nombre de 64 bits*/) { static unsigned long i; for(i=0; i<size; i++, add++) { *add = 0x8000000000000000;} }
Oui vous avez raison un " add++ " ( incrementation) prend moins de temps qu'une addition " ( add + i) ".
Dernière modification par Bktero ; 05/10/2014 à 12h49. Motif: Balises CODE
...C'est FORCÉMENT encore plus lent avec malloc() qu'en mettant i directement en variable locale!
D'après vous, le pointeur vers la donnée malloquée, où va-t-il être stocké, hein?
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Je vous remercie tous pour votre aide
De rien
Si tu n'as plus de question sur ce sujet, tu peux cliquer sur le bouton en bas de page.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager