web-dev-qa-db-fra.com

Quelle est la différence entre les nombres flottants durs et mous?

Lorsque je compile du code C avec ma chaîne d'outils croisée, l'éditeur de liens imprime des pages d'avertissements indiquant que mon exécutable utilise des flottants durs mais que ma libc utilise des flotteurs souples. Quelle est la différence?

94
Evan Kroske

Les flotteurs durs utilisent une unité à virgule flottante sur puce. Les flotteurs souples émulent un dans le logiciel. La différence est la vitesse. Il est étrange de voir les deux utilisés sur la même architecture cible, car la puce possède ou non un FPU. Vous pouvez activer le virgule flottante douce dans GCC avec -msoft-float. Vous voudrez peut-être recompiler votre libc pour utiliser la virgule flottante matérielle si vous l'utilisez.

95
nmichaels

Il existe trois façons d'effectuer l'arithmétique en virgule flottante:

  • Utilisez des instructions flottantes si votre CPU a un FPU. (vite)
  • Demandez à votre compilateur de traduire l'arithmétique à virgule flottante en arithmétique entière. (lent)
  • Utilisez des instructions flottantes et un processeur sans FPU. Votre CPU générera une exception (instruction réservée, instruction non implémentée ou similaire), et si votre noyau de système d'exploitation comprend un émulateur à virgule flottante, il émulera ces instructions (la plus lente).
30
ninjalj

À strictement parler, toutes ces réponses me semblent fausses.

Lorsque je compile du code C avec ma chaîne d'outils croisée, l'éditeur de liens imprime des pages d'avertissements indiquant que mon exécutable utilise des flottants durs mais que ma libc utilise des flotteurs souples. Quelle est la différence?

Debian wiki VFP contient des informations sur les trois choix pour -mfloat-abi,

  • soft - c'est un pur logiciel
  • softfp - cela prend en charge un FPU matériel, mais le [~ # ~] abi [~ # ~] est compatible soft.
  • hard - l'ABI utilise float ou [~ # ~] vfp [~ # ~] registres.

L'erreur de l'éditeur de liens (chargeur) est due au fait que vous disposez d'une bibliothèque partagée qui transmettra des valeurs à virgule flottante dans les registres entiers. Vous pouvez toujours compiler votre code avec un -mfpu=vfp, etc. mais vous devez utiliser -mfloat-abi=softfp de sorte que si le libc a besoin d'un flottant, il est transmis d'une manière que la bibliothèque comprend.

Le noyau Linux peut prendre en charge l'émulation des instructions VFP. De toute évidence, il vaut mieux compiler avec -mfpu=none dans ce cas et que la compilation génère directement du code au lieu de s'appuyer sur une émulation du noyau Linux. Cependant, je ne pense pas que l'erreur du PO soit réellement liée à ce problème. Il est distinct et doit également être traité avec le -mfloat-abi.

bibliothèque partagée Armv5 avec CPU ArmV7 est un opposé à celui-ci; le libc était un flotteur dur mais l'application n'était que soft. Il a quelques façons de contourner le problème, mais la recompilation avec les bonnes options est toujours la plus simple.

Un autre problème est que le noyau Linux doit prendre en charge les tâches VFP (ou quoi que ce soit ARM virgule flottante est présent) pour enregistrer/restaurer les registres sur un changement de contexte.

20
artless noise

Il semble que votre libc ait été conçue pour les opérations logicielles en virgule flottante tandis que votre exe a été compilé en supposant la prise en charge matérielle de la virgule flottante. À court terme, vous pouvez forcer les flottants flottants comme indicateur de compilation. (si vous utilisez gcc, je pense que c'est -msoft-float)

À plus long terme, si le processeur de votre cible prend en charge le matériel pour les opérations en virgule flottante, vous souhaiterez généralement créer ou trouver une chaîne d'outils croisée avec un flotteur matériel activé pour la vitesse. Certaines familles de processeurs ont des variantes de modèle, certaines avec ou sans support matériel. Ainsi, par exemple, dire simplement que votre processeur est un ARM est insuffisant pour savoir si vous avez un support matériel en virgule flottante.

12
Digikata

Le calcul peut être effectué soit par du matériel à virgule flottante, soit par un logiciel basé sur l'arithmétique entière.

Le faire dans le matériel est beaucoup plus rapide, mais de nombreux microcontrôleurs n'ont pas de matériel à virgule flottante. Dans ce cas, vous pouvez soit éviter d'utiliser la virgule flottante (généralement la meilleure option), soit vous fier à une implémentation logicielle, qui fera partie de la bibliothèque C.

Dans certaines familles de contrôleurs, par exemple ARM, le matériel à virgule flottante est présent dans certains modèles de la famille mais pas dans d'autres, donc gcc pour ces familles prend en charge les deux. Votre problème semble être que vous avez mélangé les deux options.

7
starblue