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

Threads & Processus C++ Discussion :

[VC++ 2010] Problème de précision d'un double dans un environnement multi-tâche


Sujet :

Threads & Processus C++

  1. #1
    Candidat au Club
    Inscrit en
    Février 2011
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 3
    Points : 2
    Points
    2
    Par défaut [VC++ 2010] Problème de précision d'un double dans un environnement multi-tâche
    Hi à tous !

    Voilà, je vous explique mon problème:

    Lorsque je parallélise une partie de calcul avec des doubles, j'ai un problème de précision (différence à 10^-15) sur des données de type double.

    Voici un exemple de code qui illustre mon problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    #include "stdafx.h"
    #include <iostream>
    #include <time.h>
    #include <conio.h>
    #include <Windows.h>
    #include <ppl.h>
    #include <iomanip>
    int _tmain(int argc, _TCHAR* argv[])
    {
     
    	// Sequential computation
    	double Sum	= 0.48022937707356972;	
    	double Df	= 0.29988796445769539;
    	clock_t startSequential = clock();
     
    	for(int i = 0 ; i < 100 ; ++i)
    	{
    		Sum+=i*Df;
    		Sleep(1);
    	}
     
    	clock_t endSequential = clock();
    	clock_t finSequential = endSequential - startSequential;
     
    	std::cout << "--------------SEQUENTIAL--------------" << std::endl;
    	std::cout << "\tSum : " << std::setprecision(17) << Sum << std::endl;
    	std::cout << "\tTime for computation : " << finSequential << std::endl;
     
    	// Parallel computation
    	clock_t startParallel = clock();
    	Sum = 0.48022937707356972;
    	Concurrency::critical_section mutexContention;
    	Concurrency::parallel_for( 0, 100, [&]( int i )
    	{
    		mutexContention.lock();
    		Sum+=i*Df;
    		mutexContention.unlock();
    		Sleep(1);
    	});
     
    	clock_t endParallel = clock();
    	clock_t finParallel = endParallel - startParallel;
     
    	std::cout << "--------------PARALLEL CONCURRENCY--------------" << std::endl;
    	std::cout << "\tSum : " << std::setprecision(17) << Sum << std::endl;
    	std::cout << "\tTime for computation : " << finParallel << std::endl;
     
    	clock_t startParallelOpen_MP = clock();
    	int imp;
    	Sum=0.48022937707356972;
    #pragma omp parallel for reduction(+:Sum)
    	for( imp = 0 ; imp < 100 ; imp++)
    	{
    		Sum+=imp*Df;
    		Sleep(1);
    	}
     
    	clock_t endParallelOpen_MP = clock();
    	clock_t finParallelOpen_MP = endParallelOpen_MP - startParallelOpen_MP;
     
    	std::cout << "--------------PARALLEL OPEN MP--------------" << std::endl;
    	std::cout << "\tSum : " << std::setprecision(17) << Sum << std::endl;
    	std::cout << "\tTime for computation : " << finParallelOpen_MP << std::endl;
     
    	std::cout<<std::endl<<"press any key to exit..." <<std::endl;
    	_getch();
    	return 0;
    }
    Alors cet exemple présente dans un premier temps un calcul séquentiel dans lequel je fais des additions successives sur des chiffres demandant de fortes précisions sur les arrondis. Le résultat pour ce dernier est tout le temps : 1484.9256534426663

    Le problème se situe dans les deux autres cas lorsque je "parallélise" la boucle fort avec openMP ou avec l'API PPL de microsoft (uniquement disponible sous VS2010), j'obtiens des résultats qui ne sont pas vraiment déterministes, avec une erreur d'arrondi. C'est à dire que parfois j'ai 1484.9256534426654, ou 1484.9256534426661, ... L'erreur est certes "infime", mais j'ai besoin d'une telle précision De plus, à moins que je me trompe, mais les données partagées ont l'aire bien protégées

    Est ce que quelqu'un a déjà eu un problème similaire ?

    Notez que je suis sur XP SP3, que je compile avec l'option "floating point" à "precise", que je tourne sur un Core2Duo et que j'ai le même comportement avec un build sous VS2005 et 2008 (sans PPL bien sûr !).

    Merci d'avance et bonne journée

  2. #2
    Candidat au Club
    Inscrit en
    Février 2011
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 3
    Points : 2
    Points
    2
    Par défaut C'est normal !
    Oui bon c'est normal ... Le calcul de l'arrondi dépend de l'ordre des additions

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    double a = 1.0000000000000004;
    double b = 1.0000000000000004;
    double c = 1.0000000000000002;
    double sum1 = (a + b) + c; // donne 3.0000000000000009
    double sum2 = a + (b + c); // donne 3.0000000000000013 !!
    Voili voilou bonne journée

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/08/2011, 21h03
  2. problème de précision : double ou long double?
    Par pimousse3000 dans le forum C++
    Réponses: 3
    Dernier message: 24/04/2007, 19h13
  3. Réponses: 5
    Dernier message: 11/05/2006, 08h51
  4. Boutons doubles dans la barre des tâches
    Par miniil dans le forum Windows XP
    Réponses: 5
    Dernier message: 14/12/2005, 22h30

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