web-dev-qa-db-fra.com

double ou flottant, qui est plus rapide?

Je lis "C++ accéléré". J'ai trouvé une phrase qui dit "parfois double est plus rapide à exécuter que float en C++". Après avoir lu la phrase, je me suis trompé sur le fonctionnement de float et double. Veuillez m'expliquer ce point.

46
coming out of void

Dépend de ce que fait le matériel natif.

  • Si le matériel implémente le double (comme le fait le x86), alors float est émulé en l'étendant là-bas, et la conversion coûtera du temps. Dans ce cas, le double sera plus rapide.

  • Si le matériel implémente flottant uniquement, émuler double avec lui coûtera encore plus de temps. Dans ce cas, le flotteur sera plus rapide.

  • Et si le matériel n'implémente ni l'un ni l'autre, et les deux doivent être implémentés dans le logiciel. Dans ce cas, les deux seront lents, mais le double sera légèrement plus lent (plus d'opérations de chargement et de stockage au moins).

La citation que vous mentionnez fait probablement référence à la plate-forme x86, où le premier cas était donné. Mais cela n'est pas vrai en général.

49
foo

Vous pouvez trouver une réponse complète dans cet article:

Ce que tout informaticien devrait savoir sur l'arithmétique en virgule flottante

Ceci est une citation d'un thread Stack Overflow précédent, sur la façon dont les variables float et double affectent la bande passante mémoire:

Si un double nécessite plus de stockage qu'un flotteur, la lecture des données prendra plus de temps. Voilà la réponse naïve. Sur un IA32 moderne, tout dépend de la provenance des données. S'il est dans le cache L1, la charge est négligeable à condition que les données proviennent d'une seule ligne de cache. S'il s'étend sur plusieurs lignes de cache, il y a une petite surcharge. Si c'est de L2, ça prend un peu plus de temps, si c'est en RAM alors c'est encore plus long et enfin, si c'est sur disque c'est un temps énorme. Donc le choix de float ou double est moins important que la façon dont les données sont utilisées. Si vous voulez faire un petit calcul sur un grand nombre de données séquentielles, un petit type de données est préférable. Faire beaucoup de calculs sur un petit ensemble de données vous permettrait d'utiliser des types de données plus gros avec n'importe quel Si vous accédez aux données de manière très aléatoire, le choix de la taille des données est sans importance - les données sont chargées dans les pages/lignes de cache. Ainsi, même si vous ne voulez qu'un octet de la RAM, vous pouvez obtenir 32 octets transférés (c'est très dépendante de l'architecture du système). En plus de tout cela, le CPU/FPU pourrait être super-scalaire (alias pipelined). Ainsi, même si une charge peut prendre plusieurs cycles, le CPU/FPU pourrait être occupé à faire autre chose (une multiplication par exemple) qui cache le temps de chargement à un degré

29
Diego Dias

La réponse courte est: cela dépend.

Le processeur avec x87 crunch les flotteurs et double également rapidement. Le code vectorisé s'exécutera plus rapidement avec les flottants, car SSE peut croquer 4 flotteurs ou 2 doubles en une seule passe.

Une autre chose à considérer est la vitesse de la mémoire. En fonction de votre algorithme, votre processeur peut être beaucoup au ralenti en attendant les données. Le code gourmand en mémoire bénéficiera de l'utilisation de flottants, mais pas le code limité ALU (à moins qu'il ne soit vectorisé).

14
watson1180

Je peux penser à deux cas de base lorsque les doubles sont plus rapides que les flotteurs:

  1. Votre matériel prend en charge les opérations doubles mais pas les opérations flottantes, les flotteurs seront donc émulés par le logiciel et donc plus lents.

  2. Vous avez vraiment besoin de la précision des doubles. Maintenant, si vous utilisez des flotteurs de toute façon, vous devrez utiliser deux flotteurs pour atteindre une précision similaire à doubler. L'émulation d'un vrai double avec flotteurs sera plus lente que l'utilisation de flotteurs en premier lieu.

    1. Vous n'avez pas nécessairement besoin de doubles mais votre algorithme numérique converge plus rapidement en raison de la précision améliorée des doubles. De plus, les doubles peuvent offrir suffisamment de précision pour utiliser un algorithme plus rapide mais moins stable numériquement.

Par souci d'exhaustivité, je donne également quelques raisons pour lesquelles le cas contraire des flotteurs est plus rapide. Vous pouvez voir par vous-même quelles raisons dominent dans votre cas:

  1. Les flotteurs sont plus rapides que les doubles lorsque vous n'avez pas besoin de la précision du double et que vous êtes lié à la bande passante mémoire et que votre matériel ne porte pas de pénalité sur les flotteurs.

  2. Ils conservent la bande passante mémoire car ils occupent la moitié de l'espace par numéro.

  3. Il existe également des plates-formes qui peuvent traiter plus de flottants que de doubles en parallèle.

4
Peter G.

Sur Intel, le coprocesseur (de nos jours intégré) gérera les deux aussi rapidement, mais comme certains l'ont noté, le double entraîne une bande passante mémoire plus élevée, ce qui peut provoquer des goulots d'étranglement. Si vous utilisez scalar SSE (par défaut pour la plupart des compilateurs sur 64 bits), la même chose s'applique. Donc, généralement, à moins que vous ne travailliez sur un grand ensemble de données, cela ne fonctionne pas ' t importe beaucoup.

Cependant, les instructions parallèles SSE permettront de gérer quatre flottants dans une seule instruction, mais seulement deux doubles, donc ici le flotteur peut être beaucoup plus rapide.

3

Il n'y a qu'une seule raison pour laquelle les flottants 32 bits peuvent être plus lents que les doubles 64 bits (ou 80 bits 80x87). Et c'est l'alignement. En dehors de cela, les flottants prennent moins de mémoire, ce qui signifie généralement un accès plus rapide, de meilleures performances de cache. Il faut également moins de cycles pour traiter les instructions 32 bits. Et même lorsque le (co) processeur n'a pas d'instructions 32 bits, il peut les exécuter sur des registres 64 bits à la même vitesse. Il est probablement possible de créer un cas de test où les doubles seront plus rapides que les flottants et v.v., mais mes mesures d'algos statistiques réelles n'ont pas montré de différence notable.

3
Gene Bushuyev

Dans les expériences d'ajout de 3,3 pour 2000000000 fois, les résultats sont les suivants:

Summation time in s: 2.82 summed value: 6.71089e+07 // float
Summation time in s: 2.78585 summed value: 6.6e+09 // double
Summation time in s: 2.76812 summed value: 6.6e+09 // long double

Donc double est plus rapide et par défaut en C et C++. Il est plus portable et par défaut dans toutes les fonctions de bibliothèque C et C++. Alos double a une précision significativement plus élevée que float.

Même Stroustrup recommande un flotteur double:

"La signification exacte de la précision simple, double et étendue est définie par l'implémentation. Choisir la bonne précision pour un problème où le choix importe nécessite une compréhension significative du calcul en virgule flottante. Si vous ne disposez pas de cette compréhension, obtenez des conseils, prenez le temps d'apprendre ou utilisez le double et espérez le meilleur. "

Peut-être que le seul cas où vous devriez utiliser float au lieu de double est sur du matériel 64 bits avec un gcc moderne. Parce que le flotteur est plus petit; double est de 8 octets et float de 4 octets.

1
Akash Agrawal

le flotteur est généralement plus rapide. double offre une plus grande précision. Cependant, les performances peuvent varier dans certains cas si des extensions de processeur spéciales telles que 3dNow ou SSE sont utilisées).

1
P47RICK