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

Langage C++ Discussion :

Différents résultats pour le même calcul sur CPU et GPU.


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut Différents résultats pour le même calcul sur CPU et GPU.
    Bonjour, je travaille sur ma propre librarie de réseaux de neurones et en ce moment j'essaye de copier mon code CPU sur GPU (l'utilisateur aurait de choix d'utiliser le GPU ou non).

    J'ai réussi à faire fonctionner mon code sur GPU.

    Sur des petits réseaux (avec peu de calcul), ça fonctionne bien mais sur beaucoup de calculs, environ 1 fois sur 2 le résultat n'est pas exact (je tire des valeurs initiales random au début).

    par exemples :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    0.3387047350406646728515625 != 0.33870494365692138671875
    
    0.14186990261077880859375!= 0.141869843006134033203125
    Dans cette exemple j'effectue 775 mutiplications et 56 additions sur des float et le résultat GPU et CPU est légèrement différent.

    Auriez-vous une idée d'où peut venir cette erreur de calcul ? Es-ce normal ou es-ce de ma faute ?

    Je ne pense pas que ça vienne de mon algo sinon les résultats serait significativement différent.
    Es-ce que ça pourrait venir d'un truc du genre 0.5f au lieu de 0.5 et du coup il y a certain calcul qui serait fait en double sur l'un et en float sur l'autre ?

    Es-ce que x1 et x2 fournissent toujour le même résultat ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    float x1 = 0.125 * 0.587;
    float x2 = 0.125f * 0.587f;

    PS : Mon code est beaucoup trop gros pour vous le montrer ici.

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    réponse simple: non en général.

    En fait, 0.125f est un float, tandis que 0.125 est un double

    Ces deux types sont des représentations de nombres à virgule flottante.
    Si on s'épargne quelques détails techniques, la représentation est à peu près "m * 2^e" avec m et e deux entiers.
    Ainsi, 0,125 c'est à dire 1/8 se représente avec m = 1 et e = -3.

    Il y a plein de nombres qui n'ont pas de représentation exacte, car leur écriture en base 2 n'est pas limité à un certain nombre de chiffres (voire, n'est pas finie, comme 0.1)
    a priori, c'est le cas de 0.857.

    La différence entre les deux types, ce sont les tailles disponibles pour ces deux entiers.
    Ainsi, les erreurs de précisions ne sont pas les mêmes en float et en double.

    Le double étant plus précis, on recommande en général de ne faire les calculs qu'en double, et de n'utiliser les float que pour du stockage.

    Note que le problème s'empire avec les calculs, car certaines opérations ne sont pas exactes.
    Ainsi, 0.1+0.9 peut ne pas valoir 1.0.

  3. #3
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut
    Oui, ça je savais mais ce que je voulais savoir c'est si quand je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    float x = 0.125;
    float y = 0.2569 * x;
    Le compilateur fais le calcul de y en double puis convertie le résultat en float ou il effectue direcment le calcul en float ?

  4. #4
    Membre très actif Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Par défaut
    Je précise que ne souhaite pas faire mes calculs en double car cela doublerais mon temps de calculs. Je réfléchie même à effectuer mes calculs sur des floatant de 16 bits ce que doublerais quasiment mon temps de calcul sur GPU avec la nouvelle fonctionnalité de CUDA.

  5. #5
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 251
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 251
    Par défaut
    Citation Envoyé par Matthieu76 Voir le message
    Le compilateur fais le calcul de y en double puis convertie le résultat en float ou il effectue direcment le calcul en float ?
    Cela peut dépendre des compilateurs, mais bien souvent le calcul est fait dans le format du premier opérande de l'opération. Il y a préalablement une tentative de conversion implicite des opérandes suivant dans le format du premier opérande.
    Ensuite seulement, il y a tentative de conversion du résultat final vers le format de retour.

    Certains compilateurs vont, au contraire, tenter préalablement de tout convertir dans le format de retour avant d'effectuer les opérations.

    Je ne sais pas ce qui en est pour ton compilateur exactement.

    Citation Envoyé par Matthieu76 Voir le message
    Je précise que ne souhaite pas faire mes calculs en double car cela doublerais mon temps de calculs. Je réfléchie même à effectuer mes calculs sur des floatant de 16 bits ce que doublerais quasiment mon temps de calcul sur GPU avec la nouvelle fonctionnalité de CUDA.
    Si tu arrive à trouver ce format.

    Il n'existe que 2 formats officiels de nombre à virgule flottante, le format Simple Précision (32 bits) dénommé Single, ou Float selon les langages, et le format Double précision (64 bits) dénommé Double dans la plupart des langages.
    Il n'existe pas de format en dessous de 32 bits. Il existait autrefois des formats intermédiaires entre 32 et 64 bits, mais ils ont été rendu obsolète par le format Double précision et ne sont plus utilisé depuis longtemps.
    Il peut exister des formats plus précis que 64 bits, mais sont généralement propres à certains systèmes et ne sont pas reconnus par tous les langages.

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,
    Lors d'un calcul entre un float et un double, le float est systématiquement converti en double, puis l'opération est effectuée. Si le résultat attendu est un float il y aura ensuite une autre conversion vers float.
    Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield
    result types in a similar way. The purpose is to yield a common type, which is also the type of the result.
    This pattern is called the usual arithmetic conversions, which are defined as follows:
    (11.1) — If either operand is of scoped enumeration type (7.2), no conversions are performed; if the other operand
    does not have the same type, the expression is ill-formed.
    (11.2) — If either operand is of type long double, the other shall be converted to long double.
    (11.3) — Otherwise, if either operand is double, the other shall be converted to double.
    (11.4) — Otherwise, if either operand is float, the other shall be converted to float.
    (11.5) — Otherwise,...
    Attention utiliser des float pour optimiser peut être un leurre, car
    * une conversion double vers float est nettement plus coûteuse qu'une multiplication
    * souvent les coprocesseurs peuvent être plus rapides sur des calculs double.
    * mais c'est l'inverse dans le cas de calculs parallèles (p.e. 4 ou 8 multiplications simultanées)
    * je n'y connais rien en GPU, mais il fait certainement du calcul parallèle et est certainement plus optimum sur un des 2 types.

    Ton exemple indique une différence sur la 7ème décimale, or c'est justement la limite de précision des float, il ne faut pas s'attendre à mieux. C'est tout à fait possible d'avoir un résultat différent même en utilisant un même processeur en jouant sur les options de compilation (calcul flottants: fast, strict ou precise).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 26/03/2014, 17h18
  2. [XL-2003] Appel de 2 variables sur 2 itérations pour un même calcul
    Par ludivine gerber dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 08/03/2012, 12h01
  3. [XL-2003] Mystère de précision de résultat pour la même macro sur deux ordis (xls2003)
    Par agilles dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 16/12/2011, 16h07
  4. Réponses: 17
    Dernier message: 30/05/2011, 10h14

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