Virgule flottante vs les calculs d'entiers sur le matériel moderne

Je suis en train de faire quelques critiques pour les performances en C++, et nous sommes actuellement en utilisant des calculs avec des entiers pour les problèmes qui sont de nature à virgule flottante parce que "son plus rapide". Cela provoque beaucoup de problèmes gênants et ajoute beaucoup de gênant code.

Maintenant, je me souviens avoir lu sur la façon dont les calculs en virgule flottante ont été si lent à environ vers l'386 jours, où je crois (IIRC) qu'il y avait une option de co-proccessor. Mais sûrement aujourd'hui avec d'autant plus complexes et les plus puissants Processeurs, il ne fait aucune différence dans la "vitesse" si faire de point flottant ou entier de calcul? Surtout étant donné que les temps de calcul minuscule par rapport à quelque chose comme causant un pipeline de décrochage ou chercher quelque chose dans la mémoire principale?

Je sais que la bonne réponse est la référence sur le matériel cible, ce serait un bon moyen de tester cela? J'ai écrit deux petits programmes C++ et comparer les temps d'exécution avec le "temps" sur Linux, mais le temps d'exécution est trop variable (n'a pas d'aide, je suis en cours d'exécution sur un serveur virtuel). Court de passer toute ma journée consécutive, des centaines de points de référence, faire des graphiques, etc. est-il quelque chose que je peux faire pour obtenir un raisonnable test de la vitesse relative? Toutes les idées ou les pensées? Suis-je complètement tort?

Les programmes que j'ai utilisé comme suit, ils ne sont pas identiques par tous les moyens:

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <time.h>

int main( int argc, char** argv )
{
    int accum = 0;

    srand( time( NULL ) );

    for( unsigned int i = 0; i < 100000000; ++i )
    {
        accum += rand( ) % 365;
    }
    std::cout << accum << std::endl;

    return 0;
}

Programme 2:

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <time.h>

int main( int argc, char** argv )
{

    float accum = 0;
    srand( time( NULL ) );

    for( unsigned int i = 0; i < 100000000; ++i )
    {
        accum += (float)( rand( ) % 365 );
    }
    std::cout << accum << std::endl;

    return 0;
}

Merci d'avance!

Edit: La plate-forme je me soucie est régulier x86 ou x86-64 fonctionnant sur Linux de bureau et les machines Windows.

Edit 2(collé à partir d'un commentaire ci-dessous): Nous avons une vaste base de code actuellement. Vraiment j'en suis venu à l'encontre de la généralisation que nous "ne doit pas utiliser float depuis entier de calcul est plus rapide" - et je suis à la recherche d'un moyen (si cela est encore vrai) pour réfuter cette prise en charge généralisée. Je me rends compte qu'il serait impossible de prédire le résultat pour nous, bref de faire tout le travail et le profilage par la suite.

De toute façon, merci à tous pour vos excellentes réponses et de l'aide. N'hésitez pas à ajouter d'autre chose :).

  • Ce que vous avez que votre test est trivial. Il y a aussi probablement très peu de différence dans l'assemblée, (addl remplacé par fadd, par exemple). La seule façon de vraiment obtenir une bonne mesure est d'obtenir une partie essentielle de votre véritable programme et le profil des différentes versions de l'. Malheureusement, cela peut être assez difficile sans utiliser des tonnes d'effort. Peut-être nous dire le matériel cible et de votre compilateur afin d'aider les gens, au moins, vous pré-existant de l'expérience, etc. À propos de votre entier d'utiliser, je suppose que vous pourriez faire une sorte de fixed_point classe de modèle afin de faciliter ce travail énormément.
  • Il y a encore beaucoup d'architectures qui n'a pas consacré de matériel de point flottant - tags expliquant les systèmes que vous aimez, vous aider à obtenir de meilleures réponses.
  • C'est un bon point. Pour le moment, nous avons une grande base de code, et je suis en train de faire l'argument selon lequel il serait essentiellement la même "vitesse" dans tous les cas. En espérant trouver des preuves pour étayer mon point de vue - pour justifier le travail de la commutation. De toute façon merci pour le modèle de classe d'idée, je vais essayer ça.
  • Norum bon point, je m'inquiète au sujet de la x86 ou x86-64 machines de bureau fonctionnant sous Linux et Windows
  • Je crois que le matériel dans mon HTC Hero (android) n'a pas de FPU, mais le matériel dans le Google NexusOne (android) n'. quelle est votre cible? desktop/server pc? les netbooks (possible bras+linux)? les téléphones?
  • Si vous voulez rapide FP sur x86, essayez de compiler avec l'optimisation de l'ESS et de génération de code. L'ESS (quelle que soit la version) peut faire au moins float ajouter, soustraire et multiplier en un seul cycle. Diviser, mod, et des fonctions supérieures sera toujours lent. Notez également que float obtient le boost de vitesse, mais généralement double ne l'est pas.
  • Point fixe entier se rapproche de la FP à l'aide de plusieurs opérations sur entiers de garder les résultats de déborder. C'est presque toujours plus lente que la simple utilisation de la extrêmement capable Unités modernes de bureau Cpu. par exemple, MAD, le point fixe, décodeur mp3, est plus lent que libmpg123, et même si c'est de la bonne qualité pour un point fixe décodeur, libmpg123 a encore moins de l'erreur d'arrondi. wezm.net/technical/2008/04/mp3-decoder-libraries-compared pour les tests de performances sur un PPC G5.
  • Voir ceci: nicolas.limare.net/pro/notes/2014/12/12_arit_speed

InformationsquelleAutor maxpenguin | 2010-03-31