IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[Calcul multiplateforme] résultats différents Mac / Linux


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 3
    Points : 1
    Points
    1
    Par défaut [Calcul multiplateforme] résultats différents Mac / Linux
    Bonjour à tous,

    je suis en train de développer un programme de simulation multiplateforme Mac/Linux, qui travaille sur du calcul flottant.
    Il est essentiel que ce programme donne les mêmes résultats sur les différentes plateformes cible.

    Je pensais que tout irait bien, compte tenu des normes IEEE sur les calculs flottant. Or, dans certains cas, des différences apparaissent au fur et à mesure des calculs. Il semblerait que cela soit le cas surtout lorsque je fais de nombreux tests (==, <=) sur les flottants dans la boucle de calcul.

    Quelqu'un aurait-il une idée pour corriger ce BIG BIG problème, ou un lien sur le net (je n'ai rien trouvé moi même) ?

    Merci !
    Nico

    Pour info :
    - le code est élémentaire : tests conditionnels, additions, multiplications, divisions, c'est tout (pas de racine, logarithmes...).
    - j'ai compilé sur Linux 2.4 avec gcc, sur mac OS X.3 avec gcc. Dans les deux cas sans optimisation.

  2. #2
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Salut.
    Les différences ne sont-elles pas négligeables ?
    Un historique local pour Visual Studio 2005 et 2008 :
    http://www.codeplex.com/VLH2005

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    'lu,

    Négligeables, euh, voyons... Deux réponses.

    Tout d'abord, non, je ne peux pas me permettre de les négliger.
    Puisqu'il s'agit d'un simulateur, elles vont s'amplifier avec le temps. Pour, au finish et après qqs heures ou jour de travail, donner des résultats totalement incomparables. Compte tenu du fait que les divers utilisateurs sur les diverses plateformes doivent travailler ensemble, échanger des données (des modèles, etc), ce n'est pas du tout "négligeable".

    Ceci dit, OUI, ces erreurs sont négligeables, en ce sens qu'elles sont très petites. Le problème, c'est que leur cumul finit par foutre le boxon.

  4. #4
    Membre du Club
    Inscrit en
    Janvier 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 36
    Points : 43
    Points
    43
    Par défaut Re: [Calcul multiplateforme] résultats différents Mac / Linu
    Citation Envoyé par Nicolas38
    Bonjour à tous,
    Je pensais que tout irait bien, compte tenu des normes IEEE sur les calculs flottant. Or, dans certains cas, des différences apparaissent au fur et à mesure des calculs. Il semblerait que cela soit le cas surtout lorsque je fais de nombreux tests (==, <=) sur les flottants dans la boucle de calcul.
    tu les fait comment tes comparaison ?
    ne jamais faire directement de comparaison impliquand une egalite entre des flottant ... toujours rajouter un epsilon.

    soit dit en passant les resultats sur des flottant sont susceptible de changer entre differents couple compilateur/processeur .. c'est normal

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Citation Envoyé par Nicolas38
    'lu,

    Négligeables, euh, voyons... Deux réponses.

    Tout d'abord, non, je ne peux pas me permettre de les négliger.
    Puisqu'il s'agit d'un simulateur, elles vont s'amplifier avec le temps. Pour, au finish et après qqs heures ou jour de travail, donner des résultats totalement incomparables. Compte tenu du fait que les divers utilisateurs sur les diverses plateformes doivent travailler ensemble, échanger des données (des modèles, etc), ce n'est pas du tout "négligeable".

    Ceci dit, OUI, ces erreurs sont négligeables, en ce sens qu'elles sont très petites. Le problème, c'est que leur cumul finit par foutre le boxon.
    C'est très embettant... cela remet vraiment en cause la qualité de ton simulateur. Si ta resolution mathematique n'est pas stable (ce que tu décris) alors il n'y a pas de raison que tu obtiennent une valeur valable...

    Au contraire, si ta resolution est stable, peu importe les arrondis, tu convergera vers la meme solution...

    Note on ne fait jamais de == entre flottants...

  6. #6
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Citation Envoyé par Gandalf
    Note on ne fait jamais de == entre flottants...
    En d'autres termes, soit x et y deux flottants de type double, remplacer ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (x == y)
    {
       //...
    }
    Par ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (fabs(x - y)  < std::numeric_limits<double>::epsilon())
    {
       //...
    }
    Cependant, je doute que ces précisions résolvent le problème initial.
    Un historique local pour Visual Studio 2005 et 2008 :
    http://www.codeplex.com/VLH2005

  7. #7
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 17
    Points : 20
    Points
    20
    Par défaut
    tres étrange.

    Cependant, je te dirais - sans etre sur bien sur que ça vienne de la - que les processeurs Mac et PC sont en Endian différents.
    Je sais que ça pose probleme sitot que tu as passage de données d'un systeme a l'autre, ou alors castage violent de char* sur short* par exemple.
    Ce codage joue peut etre au niveau des float, mais je suis étonné.

    Vérifie si tu n'as pas de castages bourrins comme cela.
    Ensuite, je confirme ce qu'on dit les autres : jamais de == sur des float ou double

  8. #8
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 17
    Points : 20
    Points
    20
    Par défaut
    essaie, a tout hasard, de faire afficher les sizeof(double) et sizeof(float) sur les 2 systemes : peut etre qu'ils ne codent tout deux pas sur le meme nombre d'octets :
    (tout comme "int" qui, a l'origine, était sur 2 octets)
    cela pourrait éventuellement venir de la...

    Peut etre que les mac stockent les double sous 4 octets comme des float, alors que le PC sur 8... ça jouerait...

  9. #9
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Citation Envoyé par rolkA
    Citation Envoyé par Gandalf
    Note on ne fait jamais de == entre flottants...
    En d'autres termes, soit x et y deux flottants de type double, remplacer ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (x == y)
    {
       //...
    }
    Par ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (fabs(x - y)  < std::numeric_limits<double>::epsilon())
    {
       //...
    }
    Cependant, je doute que ces précisions résolvent le problème initial.
    Souvent on prefere une forme proportionnelle, par exemple :
    1.0-min(|x|,|y|)/max(|x|,|y|) < epsilon && x*y > 0

    mais c'est à voir en fonction des cas (attention au division par zero)

    Quand au problème initial, ce n'est pas un problème, c'est ignorer volontairement l'erreur d'arrondi qui est associée aux types folttant et qui depend entre autre du type de proc et de la taille des registres flottants...

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Re: [Calcul multiplateforme] résultats différents Mac / Linu
    Citation Envoyé par dok3
    soit dit en passant les resultats sur des flottant sont susceptible de changer entre differents couple compilateur/processeur .. c'est normal
    Oui, c'est ce que j'ai compris avec quelques lectures depuis.
    Mais il reste que les normes IEEE devraient (quand on les lit !) permettre d'éviter cela. Et je suis assez certain que ce doit être faisable, compte tenu de l'importance de la chose !

    Auriez vous une piste pour ça : document à lire, article qui y fait référence, options de compilation qui "forcent" le respect d'une norme, etc. ?


    Pour ce qui est des comparaisons, je fais ça avec des < ou >, et parfois avec des <= et >= .
    Pour ce qui est des "epsilon", ma fois, j'étais au courant, mais en même temps le fichier limits.h définit ses propres "epsilon"... et oui, je l'avoue, le code dont je parle est une bibliothèque C, pas C++ .

    A moins que C++ soit blindé face à ces problèmes (ce dont je doute, cf le "quote" de dok3 ci dessus), et que le HIC provienne du code en C - de sorte que je doive reposer ces questions sur le forum C ?

  11. #11
    Membre du Club
    Inscrit en
    Janvier 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 36
    Points : 43
    Points
    43
    Par défaut
    pour < et > pas de probleme mais <= et >= implique un test d'egalite ... donc besoin d'un epsilon

    la norme IEEE c'est beau mais la realite c'est mieux, la precision des calculs depends du couple compilateur/processeur, il faut faire avec.

    Si une solution miracle existe je ne la connais pas, mais personne ne peux tout savoir, surtout pas moi ... alors ... peut etre

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Si tes deux processeurs faisaient la même chose, on pourrait en effet s'attendre à avoir les même résultats. Le problème, AMA, est que comme tu utilises des compilateurs différents, ils optimisent différemment, et donc les deux processeurs ne font pas les mêmes calculs. Pour vérifier, mon hypothèse, il pourrait être intéressant de comparer les résultats sans aucune optimisation, mais comme les processeurs modernes optimisent à la volée, je ne vois pas vraiment comment faire.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  13. #13
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut Re: [Calcul multiplateforme] résultats différents Mac / Linu
    Pourtant il a dit:

    Citation Envoyé par Nicolas38
    - j'ai compilé sur Linux 2.4 avec gcc, sur mac OS X.3 avec gcc. Dans les deux cas sans optimisation.
    On pourrait éventuellement comparer le code assembleur généré ? Les machines n'étant pas les mêmes çà me parait tendu
    Un historique local pour Visual Studio 2005 et 2008 :
    http://www.codeplex.com/VLH2005

  14. #14
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Citation Envoyé par Gandalf
    1.0-min(|x|,|y|)/max(|x|,|y|) < epsilon && x*y > 0
    mais c'est à voir en fonction des cas (attention au division par zero)
    Suffit juste d'inverser les conditions (puisque si x*y>0, alors x!=0 et y!=0), et profiter de la short-circuit evaluation...
    Mais à la reflexion ton test me parraît étrange : et si x=y=0.0 ?

    Si les systèmes s'échangent des données, ne peut tu pas les synchroniser périodiquement ? (Ca implique que le plus rapide attende l'autre, je sais...)

    Une autre solution, c'est la virugle fixe : tu remplace tes flottants par une classe qui possède un int pour la partie entière et un int pour la partie décimale. Dans certains cas ça accèlère même les calculs !
    De quelle précision à tu exactement besoin en partie décimale ?
    Gaïa n'est pas une marchandise.

  15. #15
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Je me demande si il ne faudrais pas coder tes operateurs en assembleur afin d'etre certain que les calculs soient fait de la meme maniere...

    Dailleur je me demande si on insere du code assembleur dans un code c++ si le compilo vas passer dessus et l'optimiser ou pas ?
    J'aime pas les épinards... Mais alors pas du tout

  16. #16
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 61
    Points : 24
    Points
    24
    Par défaut
    dans pas mal de cas, j'ai prefere utiliser des long int plutot que des float, en multipliant simplement toutes les valeurs par la precision minimal de tes float.... genre, si tes float vont jusqu'a 10E-8, tu multiplie tout par 10E8 et tu utilise ca dans ton programme...

    bon ok c'est pas tres propre, mais dans mon cas j'utilisais ca pour des appli plutot monetaires, ou on m'a gentiment explique que mettre des sous en float etait une heresie totale ^_^ (avec les float tu arrive toujours a avoir un 0.00000001 qui reste quelque part, au bout d un moment ca fait un petit trou dans la caisse... et si chaque programme le fait, ca devient du detournement de fond involontaire ) ... bref tout ca pour dire que je multipliait donc par 10E2 pour eviter ces problemes, voir 10E4 je crois dans le cas d'appli plus pointues (bourse etc...)

    a voir selon la precision de ton simulateur, mais clairement les float c'est vraiment lourd a gerer ^_^ (et encore maintenant ca va a peu pres, a l'epoque des K6 il faisait pas bon de faire tourner une appli avec des float sur un amd ^_^ )

    PS: lol l'etudiant qui va chercher ses souvenir de quand j'etais jeune... bientot la retraite !!

Discussions similaires

  1. Réponses: 13
    Dernier message: 01/06/2011, 15h58
  2. résultat différent de la fonction [pack] entre Linux et Windows
    Par ledannois dans le forum Général Python
    Réponses: 3
    Dernier message: 25/05/2009, 11h22
  3. [float] Calcul et résultat différent
    Par Kerod dans le forum C++
    Réponses: 22
    Dernier message: 16/03/2008, 16h12
  4. Réponses: 4
    Dernier message: 25/02/2008, 07h42
  5. Encode - Decode : probleme, résultats différent.
    Par barok dans le forum Administration
    Réponses: 1
    Dernier message: 26/08/2005, 10h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo