Avantages relatifs du calcul à virgule fixe vs virgule flottante?


9

J'ai un système de traitement du signal numérique qui fonctionne sur une machine rapide x86 utilisant des nombres à virgule flottante double précision . Il m'est venu à l'esprit que je n'utilise pas vraiment l'énorme plage dynamique de la représentation en virgule flottante - toutes les quantités s'intègrent facilement dans la plage ± 32768.

Ma question: est-il possible que le passage aux calculs à virgule fixe apporte un avantage en termes de précision numérique (haute priorité) ou de temps de calcul (basse priorité)?

Bien sûr, la réponse dépend du nombre de bits disponibles pour un calcul à virgule fixe. Combien de bits de précision les systèmes à virgule fixe typiques utilisent-ils? Est-il possible de faire efficacement des calculs à virgule fixe, avec, disons, 64 bits ( partie entière 16 bits, partie fractionnaire 48 bits ) sur x86-64?

J'avais toujours pensé que les calculs à virgule fixe n'étaient utilisés que dans des situations où la puissance du processeur est limitée - est-il judicieux d'utiliser des calculs à virgule fixe lorsque la puissance du processeur n'est pas un problème?


Avez-vous vraiment besoin de plus que les ~ 15 chiffres significatifs qu'une valeur à virgule flottante double précision vous donne? Bien que les généralisations générales soient mauvaises, je dirais que si vous regardez l'agrégat de tous les systèmes DSP à virgule fixe, les entiers 16 bits sont probablement le format le plus courant.
Jason R

Réponses:


7

La précision numérique des entiers ne sera meilleure que la précision numérique des flottants que si la résolution entière est meilleure. Les doubles ont 52 bits fractionnaires, donc les flotteurs à double précision ont une résolution pire que les entiers autour de , ce qui est beaucoup plus grand que 32 768 ( 2 15 ). Donc, non, la précision numérique ne sera pas meilleure si vous passez à des entiers.252215

Le deuxième problème est la vitesse. La réponse est: cela dépend du matériel. Si vous exécutez votre programme sur un processeur de signal numérique qui a plusieurs cœurs de multiplication / accumulation de points fixes, alors oui, ce sera beaucoup plus rapide en point fixe. Sur une puce x86, en revanche, elle sera probablement plus lente en virgule fixe. J'ai fait exactement ce dont vous parlez une fois et j'ai vu mes délais d'exécution augmenter.

Après avoir fait quelques recherches sur Internet, j'ai découvert que c'était courant. La raison en est qu'il dispose d'un processeur à virgule flottante dédié qui ne fait rien lorsque vous passez au point fixe, tandis que le matériel à virgule fixe est partagé avec l'action à virgule fixe régulière, telle que l'arithmétique des pointeurs.

Si vous souhaitez accélérer le traitement, la méthode consiste à passer de flotteurs double précision à flotteurs simple précision. Cela devrait produire une augmentation significative de la vitesse. Cela réduirait bien sûr votre précision numérique.


Je voulais dire ce que dit cette réponse quand j'ai écrit la mienne. Celui ci est mieux. Si je ne me trompe pas, j'ai lu quelque part que sur certains ordinateurs (64 bits peut-être?), Le type de virgule flottante matérielle native est double, donc l'utilisation de flotteurs à simple précision (quatre octets) pourrait en réalité être plus lente. C'est quelque chose à prendre en considération de toute façon.
heltonbiker

Les flotteurs simple précision ont des mantisses de 23 bits, les doubles ont 52 bits.
Paul R

Je propose un entier 16 bits + une fraction 48 bits comme alternative à la virgule flottante double précision. J'ai mentionné 32768 pour indiquer que mes valeurs s'intégreront facilement dans cette plage. Étant donné la restriction de ces valeurs, je pense que Q16.48 fournirait une plus grande précision numérique que la virgule flottante double précision.
nibot

1
@ nibot OK. Les doubles auraient une meilleure précision de -16 à +16, et les entiers fractionnaires auraient une meilleure précision ailleurs jusqu'à -32769 et +32768. Bien entendu, ils ne pouvaient rien représenter au-delà de cela. Ils seraient également plus lents que les doubles. Pour moi, la portée limitée et la vitesse lente seraient des disjoncteurs, mais YMMV.
Jim Clay

6

Les avantages du virgule fixe sont principalement en termes de puissance (par exemple lorsque vous avez le choix du matériel de processeur, ou que le processeur est bon pour arrêter les unités fonctionnelles inutilisées). En effet, les unités à virgule fixe sont généralement plus petites (moins de transistors, fils plus courts, moins de capacité à surmonter par MAC) pour une technologie et un taux de problème de fonctionnement donnés, que la virgule flottante.

Cependant, une grande quantité de processeurs contemporains courants (serveur, PC et même mobile), ont des FPU plus nombreux et plus rapides (en particulier des unités FP simple précision) que des multiplicateurs entiers, et la majeure partie de la puissance du système ne provient pas de l'utilisation du FPU, donc en utilisant fixe -point aura peu ou pas d'avantages pour le calcul DSP typique sur ces produits, et peut probablement être un inconvénient en termes de performances pures. En utilisant la technologie actuelle, tout avantage du virgule fixe s'accumulera principalement dans de minuscules produits intégrés, tels que des appareils de la taille d'un bouton.

Cependant, considérez également les empreintes de mémoire et de cache du processeur. L'utilisation intelligente de types de données plus petits (short int et float) pour adapter complètement un grand calcul dans le cache de données peut compenser tous les avantages de la bande passante FPU.


2
+1 pour la mention de l'importance des problèmes de cache en termes de performances. Sur les processeurs x86 modernes, la conception de votre algorithme avec le cache à l'esprit peut avoir un effet énorme sur les performances.
Jason R

5

Préférez les flotteurs simple précision aux doubles - cela réduira de moitié la bande passante de votre mémoire, l'encombrement du cache et les exigences de stockage, et accélérera certaines opérations mathématiques. Il ouvre également la possibilité de SIMD 4 voies si une optimisation supplémentaire est nécessaire.

Le point fixe ne vaut vraiment la peine que si vous n'avez pas de FPU - la plupart des processeurs x86 modernes ont deux FPU, il n'y a donc rien à gagner à utiliser un point fixe, et les performances peuvent même être nettement moins bonnes avec un point fixe. (Notez également que le point fixe nécessite des instructions supplémentaires par rapport au point flottant pour des opérations telles que la multiplication.)


Je souhaite augmenter la précision numérique, pas la réduire.
nibot

Comment voyez-vous le point fixe améliorer la précision numérique par rapport à un double, qui a déjà 52 bits de précision et une énorme plage dynamique?
Paul R

Eh bien, je pourrais utiliser un format à virgule fixe avec plus de 52 bits.
nibot

Étant donné que vous avez apparemment besoin d'au moins 16 bits pour la partie entière de votre représentation en virgule fixe, cela vous prendra bien plus de 64 bits, donc vous cherchez probablement un format pour lequel votre CPU n'a même pas d'instructions natives entières. Dans ce cas, vous pouvez tout aussi bien utiliser une grande bibliothèque d'entiers existante ou similaire. La question la plus importante à laquelle répondre est cependant: de quelle précision avez-vous vraiment besoin ?
Paul R

3

En plus des très bonnes réponses fournies ici, quelques points méritent d'être ajoutés:

  • Il existe des situations dans lesquelles même si vous avez des exigences très basiques sur la plage dynamique des données que vous traitez, vous aurez toujours besoin d'une très bonne précision pour certaines des opérations qui y sont effectuées - par exemple, vous voudrez appliquer un filtre IIR qui nécessite des coefficients relativement faibles; et les tronquer provoquerait des instabilités. Dès que votre système a des commentaires, il y a de fortes chances que les problèmes de quantification / troncature vous mordent lorsque vous utilisez un point fixe - vous devez être beaucoup plus prudent sur des choses comme la topologie du filtre et les schémas de troncature / économie de fraction.
  • Contrairement à de nombreuses architectures DSP / DSC, le x86 n'a pas d'opérations entières saturées (enfin, il est là dans SSE, pas sur le code scalaire standard). Cela signifie qu'en cas de débordement, de mauvaises choses peuvent se produire - les valeurs changent les signes et «enveloppent». Vous devez être extrêmement prudent avec les débordements et la plage dynamique, ou saupoudrer tests sur les plages d'opérandespartout dans votre code. Cela peut sérieusement nuire aux performances. En comparaison, la virgule flottante résiste mieux à ces problèmes, car la grande plage dynamique vous donne plus de "marge" et les débordements n'entraîneront pas de pannes catastrophiques. La plupart du code de traitement du signal audio exécuté sur les ordinateurs de bureau utilise la plage -1,0 .. 1,0, simple ou double précision; cela donne donc plus de centaines de dB de marge. J'ai écrit du code de traitement du signal audio avec les deux approches, et lors de l'utilisation de virgule flottante, il n'y a que quelques endroits où je dois explicitement couper / saturer le signal - généralement juste à la fin de la chaîne de traitement du signal ou dans des endroits où des retours se produisent.

1

Quelques points à considérer:

  • La plupart des processeurs modernes optimisent le nombrecrunching à virgule flottante depuis de nombreuses années, et même les GPU sont déjà utilisés avec beaucoup de succès;
  • Les calculs à virgule fixe endommagent vos données et peuvent causer de graves problèmes lorsque les opérations arithmétiques ne sont pas bien conditionnées (c'est pourquoi les nombres à virgule fixe ont été remplacés par des virgules flottantes);
  • Même si vous utilisez des shorts signés pour CONTENIR vos données (les enregistreurs de lots utilisent une précision de 16 bits), les CALCULS doivent être effectués en virgule flottante, puis reconvertis en entiers, sinon il pourrait y avoir des artefacts tels que la quantification et l'aliasing.

En dernier mot, je pense que nos données du monde réel sont précieuses et que le calcul numérique aveugle de l'ordinateur est un humble travail subalterne. L'ordinateur doit être mis à contribution pour vos données et pour vous, et ne pas être traité comme si c'était la vraie star de l'émission.


Je ne voulais pas impliquer que j'utiliserais des courts métrages 16 bits pour contenir mes quantités, mais plutôt quelque chose comme un format à virgule fixe 64 bits avec une partie entière 16 bits et une partie fractionnaire 48 bits. La motivation est que, si je n'utilise pas la plupart des bits d'exposant au format à virgule flottante, ma précision numérique s'améliorerait-elle si j'utilisais plutôt ces bits pour fournir des chiffres significatifs supplémentaires?
nibot

215

Une dernière chose: il me semble que StackOverflow (au lieu de DSP.SE, ici) serait l'endroit idéal pour obtenir des raisons plus profondes sur les avantages et les inconvénients d'un format par rapport à l'autre.
heltonbiker
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.