8
votes

Les frais généraux de la coulée double pour flotter?

J'ai donc des mégaoctets de données stockées comme des doubles qui doivent être envoyées sur un réseau ... Maintenant, je n'ai pas besoin de la précision qu'une double offre, donc je souhaite les convertir en un flotteur avant de les envoyer sur le réseau. Quelle est la surcharge de simplement faire: xxx

Je ferai cette opération plusieurs millions de fois toutes les quelques secondes et je ne veux rien ralentir. Merci

EDIT: Ma plate-forme est x64 avec Visual Studio 2008.

edit 2: Je n'ai aucun contrôle sur la façon dont ils sont stockés.

c c++

13 commentaires

Cela dépend de votre compilateur et de votre processeur. La surcharge réelle apparaîtra dans votre assemblée - regardez la vue ASM dans le débogueur de Visual Studio. (ou l'option -s pour GCC)


Mesurez-le et voyez.


Avec tout le respect due, c'est pourquoi je l'ai posé à ce sujet ... Je ne voulais pas le tester et voir hahaha.


Si vous n'avez pas besoin de la précision, pourquoi ne les stockez-vous pas comme des flotteurs à la place?


Je n'ai aucun contrôle sur la façon dont ils sont stockés sinon je voudrais :(


Essayez-vous d'accélérer votre trafic réseau? Êtes-vous sûr que vous changez de flotteur au double ferait cela?


Eh bien, cela réduirait la taille des données que j'envoie.


Encore une fois, je suggère que vous regardez l'assemblée.


Ok, alors recherchez le manuel des cycles de chacune de ces instructions de l'ASM, nourrissez celle de votre CPU Hertz et que ce sera votre pire des frais généraux. Un processeur moderne fera mieux que cela en raison des instructions et des pipelines entrelacées, mais maintenant, vous avez maintenant une limite supérieure.


S'ils sont ieee 754 doubles et flotteurs, la conversion entre eux est une question de quelques quarts de travail. Le temps passé par un million de conversions est négligeable. Par rapport aux vitesses du réseau, il est pratiquement zéro.


"Vous devez le mesurer" semble être devenu le poulet de la réponse: aucun besoin de penser à la question.


Pourquoi est-ce que ce moulinage est sorti? Examiner manuellement l'assemblage et compter les cycles de processeur est compliqué (parce que vous devez apprendre à faire quelque chose), lent (parce que vous le faites manuellement) et inexact (vous vous trompez parce que vous ne prenez pas en compte des pipelines, Entrelacement, etc., toutes les choses intelligentes du processeur que vous n'êtes pas assez intelligent pour). La mesure est simple, rapide et précise. Suis-je en train de tricher si je choisis le bon outil pour gagner du temps?


De plus, mesurer cela vous donnera une réponse pour un compilateur, avec un ensemble d'options de compilateur, sur un système d'exploitation, sur un processeur. Éventuellement aussi affecté par d'autres facteurs. Évidemment, la réponse à une question comme celle-ci dépend beaucoup du compilateur et de la plate-forme, mais je trouve une réponse comme "il faut quelques changements de bits" beaucoup plus utiles que "la mesure" car je peux corréler des changements de bits à d'autres systèmes Wheras La mesure des résultats des résultats n'a pas de sens partout, mais où elle a été testée. La mesure est idéale pour tester une chose par rapport à une autre sur le même système, mais mauvais pour les absolus.


8 Réponses :


9
votes

Cela dépend de votre mise en œuvre de bibliothèques C ++. Testez-le et voyez.


0 commentaires

2
votes

Vous n'avez aucun choix que de les mesurer vous-même et de voir. Vous pouvez utiliser des minuteries pour les mesurer. On dirait que certains ont déjà mis en œuvre une nette Classe de la minuterie C ++


0 commentaires

3
votes

Gardant à l'esprit que la plupart des compilateurs traitent avec doubles beaucoup plus efficacement que floatts - beaucoup promeuvent float à double < / Code> Avant d'effectuer des opérations sur eux - je envisagerais de prendre le bloc de données, de la zipper / la compressant, puis de l'envoi du bloc comprimé. Selon les données de vos données, vous pouvez obtenir une compression de 60 à 90%, vs. Les 50% que vous obtiendriez la conversion des valeurs de 8 octets à quatre octets.


7 commentaires

La compression serait certainement plus lente que la coulée double à flotter, même si les performances numériques des opérations arithmétiques sont la même (pas mieux, comme les deux seront probablement promus au format étendu en interne).


Hmmm très intéressant ... Je ne suis pas sûr que cela devra être compressé (probablement non), mais cela pourrait être une meilleure solution puis la convertir. Des algorithmes de compression sur le dessus de votre tête? Merci


@fortran - Absolument, quelle que soit la quantité de temps de transmission plus lente et de la transmission encore une seule observation directe.


@ Polaris878 - Considérez la compression LZW. Je suis à peu près sûr que c'est la copie écrite, mais vous devriez pouvoir trouver une implémentation utilisable. Ou au moins cela vous dirigera vers une solution!


Quels processeurs favorisent float à double ? Êtes-vous par hasard le confondant avec x86 / x64, qui favorise les deux float et double à long double lors du chargement dans les registres de FPU, avec des paramètres par défaut ?


Avez-vous des raisons de croire que 60-90% sont raisonnables? Les chiffres que je sortent de mon arrière sont beaucoup plus bas que cela. Tous sauf un ou deux octets de chaque valeur sont susceptibles d'être presque aléatoires.


Comme le souligne la réponse de Peterchen, une estimation approximative suggère que le temps nécessaire pour transmettre les résultats de l'ensemble du réseau domine celui de tout calcul raisonnablement simple, une plus grande compression peut offrir une vitesse plus importante.



1
votes

Cela dépendra également de la CPU et de ce que la prise en charge de Point flottant elle a. Dans les mauvais jours (1980), les processeurs ont pris en charge les opérations entière uniquement. Les mathématiques de point flottant devaient être émulées dans des logiciels. Une puce séparée pour le point flottant (un coprocesseur ) pourrait être acheté séparément.

Les processeurs modernes ont maintenant SIMD instructions, de sorte que de grandes quantités de données à virgule flottante peuvent être traitées. immediatement. Ces instructions incluent MMX, SSE, 3DNOW! etc. Votre compilateur peut savoir comment utiliser ces instructions, mais vous devrez peut-être écrire votre code d'une manière particulière et allumer les bonnes options.

Enfin, le moyen le plus rapide de traiter les données de points flottants est dans une carte vidéo. Une autre nouvelle langue appelée OPENCL vous permet d'envoyer des tâches à la carte vidéo à traiter là-bas. < / p>

Tout dépend de la quantité de performance dont vous avez besoin.


2 commentaires

Oui, c'est exactement pourquoi ... toutes ces données vont sur la carte vidéo de l'autre côté du réseau ... Donc, je souhaite rendre les données noires et soignées avant d'atteindre le client à être rendu.


Opencl ne garantit pas le soutien des doubles et, puisqu'il ne fait aucun calcul réel, Opencl pourrait ne pas être un bon choix.



5
votes

Même si cela prend du temps, cela ne sera pas le point lent de votre application.
Votre FPU peut faire la conversion beaucoup plus rapidement que ce qu'il peut envoyer du trafic de réseau (le goulot d'étranglement sera donc probablement probablement l'écriture sur la prise).

Mais comme avec Al, c'est comme ça, c'est la mesure et voir.

Personnellement, je NE PAS Pensez à tout moment à passer ici affectera le temps réel passé à envoyer les données.


0 commentaires

4
votes

En supposant que vous parlez d'un nombre important de paquets pour expédier les données (une hypothèse raisonnable si vous envoyez des millions de valeurs) La coulée des doubles à flottez réduira probablement le nombre de paquets de réseau d'environ la moitié (en supposant que Tailleof (Double) == 8 et Tailleof (float) == 4 ).

Presque certainement, les économies dans le trafic réseau domineront le temps passé à effectuer la conversion. Mais comme tout le monde le dit, mes tests sera la preuve du pudding.


1 commentaires

Oui! C'est exactement pourquoi j'étais intéressé à faire la conversion ... quelques autres affiches ne réalisaient pas ceci :)



13
votes

Comme le dit Michael Burr, tandis que la surcharge dépend fortement de votre plate-forme, la surcharge est définitivement inférieure au temps nécessaire pour les envoyer sur le fil.


une estimation approximative:

charge utile 800Mbit / s sur un excellent fil gigabit, 25m-flotteurs / seconde.

sur un noyau unique de 2GHz, qui vous donne un cycles d'horloge 80 pour chaque valeur convertie en pause même - tout de même, et vous gagnerez du temps. Cela devrait être plus que suffisant sur toutes les architectures :)

Un cycle de chargement simple (sauf tous les retards de mise en cache) doit être inférieur à 5 cycles par valeur. Avec l'entrelacement d'instructions, les extensions SIMD et / ou la parallélisation sur plusieurs cœurs, vous risquez de faire plusieurs conversions dans un seul cycle.

En outre, le récepteur sera heureux de ne pas gérer que la moitié des données. N'oubliez pas que l'heure d'accès mémoire est non linéaire.


La seule chose qui se dispute contre la conversion serait si le transfert devrait avoir une charge de processeur minimale: une architecture moderne pourrait transférer les données de disque / mémoire au bus sans intervention du CPU. Cependant, avec des chiffres ci-dessus, je dirais que cela n'a pas d'importance dans la pratique.

[modifier]
J'ai vérifié certains chiffres, le 387 coprocesseur aurait effectivement pris environ 70 cycles pour un cycle de chargement. Sur le pentium initial, vous êtes à 3 cycles sans aucune parallélisation.

Ainsi, sauf si vous exécutez un réseau Gigabit sur un 386 ...


1 commentaires

Merci d'avoir expliqué cela au niveau bas ... C'est de bonnes choses. Lorsqu'il s'agit de beaucoup de données, chaque cycle d'horloge compte!



2
votes

Je pense que cette fonte est beaucoup moins chère que ce que vous ne le pensez, car cela n'implique aucun type de calcul. En fait, il suffit de se débarrasser de certains des chiffres de l'exposant et de la mantissa.


2 commentaires

La mise en œuvre directe est une paire FLD / FSTP (c'est-à-dire charger le double sur la pile à point flottant, écrivez-le comme flotteur). La conversion est donc probablement mise en œuvre dans du matériel. Ce serait un peu cher dans des logiciels - vous avez besoin d'arrondissement correct et de vérifier le débordement de la plage.


Après avoir vérifié le code de montage, ce sont les instructions exactes qu'il fait. Merci