IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bibliothèque standard C Discussion :

Trouver utilisations des fonctions de la libc


Sujet :

Bibliothèque standard C

  1. #1
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 16
    Points : 5
    Points
    5
    Par défaut Trouver utilisations des fonctions de la libc
    Bonjour à tous,

    je vous explique rapidement mon problème. Je développe un projet tournant sur un microcontrôleur ARM (Cortex-M4) qui possède une FPU (floating point unit) et afin de gagner un rapidité en taille du programme, je veux faire en sorte que tous les calculs se fassent avec des float et non des doubles pour éviter d'avoir des conversions de type.

    J'ai parcouru tout mon code pour rajouter des .f après les constantes numériques (ex 2.0f) et utilisé les fonctions mathématiques sur float (sqrtf, cosf, etc) mais quand je fais appel à la commande nm (arm-none-eabi-nm pour être exact) de GCC pour savoir quels sont les fonctions utilisées, je vois qu'il me reste encore des fonctions travaillant avec des doubles (des dsub, dadd, etc).

    J'aimerais donc bien trouver où ces fonctions sont appelées afin de corriger ça mais je sais pas du tout comment faire. (je suis aller faire un tour sur google mais j'ai pas trouvé ce que je voulais)

    Merci d'avance

  2. #2
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    560
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 560
    Points : 1 432
    Points
    1 432
    Par défaut
    Fait un : objdump -D executable > executable.dump pour voir par qui sont appelée ces fonctions.

  3. #3
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 16
    Points : 5
    Points
    5
    Par défaut
    Merci c'est parfait comme solution, par contre j'ai remarqué certaines choses contre lesquelles je ne peux rien faire (à priori).

    Par exemple, la fonction sqrtf() fait appel dans son code à __aeabi_f2d qui vu le nom, fait une conversion d'un float vers un double. C'est quand même étrange qu'une fonction devant travailler sur du float travaille en interne sur du double non? Ce qui m'embête c'est que du coup ça m'ajoute les fonctions que je cherche à éliminer…

    Quelqu'un sait si il existe une version float uniquement de la librairie mathématique?

  4. #4
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    560
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 560
    Points : 1 432
    Points
    1 432
    Par défaut
    Il faut poser la question au fournisseur de la libC de ta cible.
    Ta requête est légitime. Si ta FPU est simple précision c'est quand même ton droit de ne faire que du simple précision...

    Si c'est un truc open source tu peux peut-être recompiler tout le bousin avec des options spéciales => grosse galère quand même....

  5. #5
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 16
    Points : 5
    Points
    5
    Par défaut
    ouais je pense que je vais aller poser la question aux gens qui proposent le compilateur, je verrai ce qu'ils ont à me dire et je reviendrai faire le point ici, ça pourra toujours intéresser quelqu'un. En plus entre deux j'ai remarqué quelque chose, même si le FPU est capable de calculer une racine carrée, c'est uniquement les fonctions des librairies qui sont appelées, que se soit en float ou en double...

    Merci pour ton aide en tout cas, j'arrive tout de même à réduire la taille de mon code grâce à objdump

  6. #6
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 16
    Points : 5
    Points
    5
    Par défaut
    Après quelques discussions avec les gens qui fournissent le compilateur, un minimum d'optimisations doivent être activées pour l'utilisation de l'instruction du FPU pour le calcul de la racine carrée (ce que je trouve un peu bizarre tout de même).

    Ça n'empêche pas qu'il reste toujours des conversions float/double à l'intérieur de sqrtf (et de expf par la même occasion). Apparemment, cela est dû à la gestion des erreurs. Tous les floats sont convertis en doubles en sont envoyés à une fonction générique de gestion des exceptions. Le nombre retourné est donc reconverti en float avant d'être retourné par sqrtf ou expf. C'est pour ça que malgré tous mes efforts, il restait des fonctions travaillant sur des doubles.

    En espérant que ça puisse éclairer quelqu'un dans la même situation que moi

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 483
    Points : 13 685
    Points
    13 685
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Pourrais-tu nous expliquer un peu plus en détails pourquoi tu préfères utiliser des floats plutôt que des doubles ? Le sujet m'intéresse

  8. #8
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 16
    Points : 5
    Points
    5
    Par défaut
    La raison est assez simple en fait.

    Quand on programme un microcontrôleur, on a pas beaucoup de puissance de calcul à disposition et à part si tu tapes dans le haut de gamme, t'as pas de FPU intégrée qui te permet de réaliser tes calculs sur les nombres en virgule flottante et donc tout est géré par des librairies (qui se débrouillent pour faire ces calculs avec des entiers car c'est tout ce que le CPU sait traiter).

    Donc, à part si c'est nécessaire, ça sera toujours plus rapide et plus économe en mémoire de travailler uniquement avec des floats (32bits) qu'avec des doubles (64bits). En plus, sans la présence de FPU, si l'utilisation des deux est mélangée dans le programme, ça implique de charger les librairies de calculs sur floats, celles sur doubles et celles de conversion entre les deux types. Quand on sait que sur un petit microcontrôleur d'entrée de gamme la mémoire pour le programme se résume à quelques KB ou quelques dizaines de KB, faut faire attention à ce qu'on fait.

    Pour finir et pour revenir à mon cas présent, j'ai affaire à un microcontrôleur qui possède une FPU mais qui travaille uniquement sur des floats. La multiplication de deux floats se fait donc en un coup d'horloge alors que la multiplication de deux doubles et bien plus longue car des fonctions sont appelées pour gérer ce cas particulier. Le côté mémoire me gêne moins car j'ai 1MB à disposition, quand on vient du monde du PC ça paraît ridicule mais dans le monde de l'embarqué, c'est énorme.

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 483
    Points : 13 685
    Points
    13 685
    Billets dans le blog
    1
    Par défaut
    Je connais bien le monde des micro, ma question était vraiment spécifique "double vs float sur CM4 avev FPU (CM4F)"

    Si je comprends bien, tu cherches les perfs plus que la précision (qui est apportée par le type double) ?

    Tous les CM4F ont des FPU en 32 bits ou certains peuvent avoir des FPU 64 bits ?

    Quand je vois l'assembleur généré en mode -mfloat-abi=hard, je me demande comment ça peut se faire en un coup d'horloge ? Tu parles uniquement de la partie "la FPU a son entrée positionnée, il faut un coup d'horloge pour produire le résultat" et non de toute la convention call ?

  10. #10
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 16
    Points : 5
    Points
    5
    Par défaut
    D'après le site d'ARM "single precision Floating Point Unit " donc non, pas de double sur CM4F.

    Oui j'ai besoin de perfs car il est embarqué dans un projet de robotique et je traite les données des capteurs (accéléromètre, gyroscope, magnétomètre, une IMU quoi), en temps réel à une fréquence de 100Hz, et tout ça avec des quaternions et faut que tout le reste puisse tourner à côté (asservissements, etc). Et de toute façon, étant donné la précision des capteurs et leur bruit, les doubles ne serviraient vraiment à rien.

    Tout à fait pour l'histoire du coup d'horloge. Y'a besoins de quelques instructions autours de l'instruction FPU pour que le calcul puisse se faire.

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 483
    Points : 13 685
    Points
    13 685
    Billets dans le blog
    1
    Par défaut
    J'ignorais ce qu'était un quaternion, j'apprends des choses

    Ton histoire de capteurs bruités me fait me dire qu'utiliser des doubles dans le projet que je prépare et qui travaille aussi avec des capteurs sur CM4F n'est peut-être pas la meilleure des idées... Il faut que j'y pense dans la suite ^^

    Par curiosité, j'ai écrit une bête opération entre des doubles et entre des floats pour voir l'assembleur. J'utilise l'ABI hard pour compiler et voilà l'assembleur généré pour ceux que ça intéresse :
    double d(double a, double b)
    {
       0:	b480      	push	{r7}
       2:	b085      	sub	sp, #20
       4:	af00      	add	r7, sp, #0
       6:	ed87 0b02 	vstr	d0, [r7, #8]
       a:	ed87 1b00 	vstr	d1, [r7]
    	return a + b;
       e:	ed97 6b02 	vldr	d6, [r7, #8]
      12:	ed97 7b00 	vldr	d7, [r7]
      16:	ee36 7b07 	vadd.f64	d7, d6, d7
    }
      1a:	eeb0 0b47 	vmov.f64	d0, d7
      1e:	f107 0714 	add.w	r7, r7, #20
      22:	46bd      	mov	sp, r7
      24:	bc80      	pop	{r7}
      26:	4770      	bx	lr
    00000028 <f>:
    float f(float a, float b)
    {
      28:	b480      	push	{r7}
      2a:	b083      	sub	sp, #12
      2c:	af00      	add	r7, sp, #0
      2e:	ed87 0a01 	vstr	s0, [r7, #4]
      32:	edc7 0a00 	vstr	s1, [r7]
    	return a + b;
      36:	ed97 7a01 	vldr	s14, [r7, #4]
      3a:	edd7 7a00 	vldr	s15, [r7]
      3e:	ee77 7a27 	vadd.f32	s15, s14, s15
    }
      42:	eeb0 0a67 	vmov.f32	s0, s15
      46:	f107 070c 	add.w	r7, r7, #12
      4a:	46bd      	mov	sp, r7
      4c:	bc80      	pop	{r7}
      4e:	4770      	bx	lr
    
    Je n'ai pas de doc CM4 pour voir le nombre des cycles instructions vadd.f64 et vadd.f32 mais on se doute bien que ça va être plus long. J'ai testé aussi en sommant un float et un double et en retournant un float, ce n'est pas une bonne idée ^^

  12. #12
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 16
    Points : 5
    Points
    5
    Par défaut
    C'est par ici la doc du jeu d'instruction du FPU du CM4F : http://infocenter.arm.com/help/index.../BEHJADED.html

    Ce qui est bizarre, c'est qu'ils ne mentionnent pas l'instruction vadd.f64 donc je sais pas trop comment c'est géré.

    Pour l'histoire des capteurs bruités et des doubles, je suis pas un pro du tout (j'ai même pas encore fini mes études, plus que quelques moi ^^), mais ça me parait logique.

    EDIT :

    Tu as bien compilé ton code pour un CM4F? Perso pour les deux fonctions d'addition j'ai :

    ASM de la fonction sur doubles
    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     800054c:	b580      	push	{r7, lr}
     800054e:	b084      	sub	sp, #16
     8000550:	af00      	add	r7, sp, #0
     8000552:	ed87 0b02 	vstr	d0, [r7, #8]
     8000556:	ed87 1b00 	vstr	d1, [r7]
     800055a:	e9d7 0102 	ldrd	r0, r1, [r7, #8]
     800055e:	e9d7 2300 	ldrd	r2, r3, [r7]
     8000562:	f7ff fe41 	bl	80001e8 <__adddf3>
     8000566:	4602      	mov	r2, r0
     8000568:	460b      	mov	r3, r1
     800056a:	ec43 2b17 	vmov	d7, r2, r3
     800056e:	eeb0 0a47 	vmov.f32	s0, s14
     8000572:	eef0 0a67 	vmov.f32	s1, s15
     8000576:	f107 0710 	add.w	r7, r7, #16
     800057a:	46bd      	mov	sp, r7
     800057c:	bd80      	pop	{r7, pc}
     800057e:	bf00      	nop

    ASM de la fonction sur floats
    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     8000580:	b480      	push	{r7}
     8000582:	b083      	sub	sp, #12
     8000584:	af00      	add	r7, sp, #0
     8000586:	ed87 0a01 	vstr	s0, [r7, #4]
     800058a:	edc7 0a00 	vstr	s1, [r7]
     800058e:	ed97 7a01 	vldr	s14, [r7, #4]
     8000592:	edd7 7a00 	vldr	s15, [r7]
     8000596:	ee77 7a27 	vadd.f32	s15, s14, s15
     800059a:	eeb0 0a67 	vmov.f32	s0, s15
     800059e:	f107 070c 	add.w	r7, r7, #12
     80005a2:	46bd      	mov	sp, r7
     80005a4:	bc80      	pop	{r7}
     80005a6:	4770      	bx	lr

    De mon côté j'ai un appel à __adddf3 pour faire l'addition sur deux doubles, et pas une instruction FPU

  13. #13
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 483
    Points : 13 685
    Points
    13 685
    Billets dans le blog
    1
    Par défaut
    C'est en effet étonnant... J'ai bien l'option -mcpu=cortex-m4 pourtant. En regardant sur le net, vadd.f64 semble être une instruction de Cortex-R4. D'ailleurs, si je met l'option -mcpu=cortex-r4, j'ai le même résultat. Ma chaine de compilation semble dérailler quelque peu...

    Btw, le document que tu montres est marqué comme "superseded" (marquage à l'arrière-plan) : c'est parce qu'il existe une version plus récente http://infocenter.arm.com/help/index.../BEHJADED.html


    EDIT : il semblerait qu'il faille rajouter l'option -mfpu pour indiquer que c'est un CM4F (préciser qu'on veut l'ABI hard ne suffirait pas à lui faire comprendre qu'elle est présente). As-tu rajouter cette option ? Quelle valeur lui as-tu donné ?

  14. #14
    Futur Membre du Club
    Inscrit en
    Janvier 2011
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 16
    Points : 5
    Points
    5
    Par défaut
    Côté GCC, j'ai comme flags (entre autres) : -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp -mfpu=fpv4-sp-d16
    Côté LD, j'ai (entre autres) : --specs=nano.specs -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp -mfpu=fpv4-sp-d16

    J'ai pas noté de différences entre softfp et hard par contre.

  15. #15
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 483
    Points : 13 685
    Points
    13 685
    Billets dans le blog
    1
    Par défaut
    C'est aussi l'option de fpu que j'ai mise. J'essayerai de penser à tester les différentes conventions la semaine prochaine.

Discussions similaires

  1. [VB.NET][Excel] utiliser des fonction Excel comme xlToRight
    Par Alexj51 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 01/03/2006, 12h10
  2. [Xml/XSl] utiliser des fonction vb
    Par ekmule dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 17/01/2006, 17h28
  3. [hibernate] utilisation des fonctions d'aggregation
    Par osopardo dans le forum Hibernate
    Réponses: 2
    Dernier message: 29/08/2005, 09h41
  4. utilisation des fonctions d'une dll
    Par jackk dans le forum C++
    Réponses: 14
    Dernier message: 15/06/2005, 16h50
  5. Utiliser des fonctions Pascal
    Par Neilos dans le forum C++Builder
    Réponses: 2
    Dernier message: 07/03/2004, 15h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo