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 :

temps de calculs très bizarre


Sujet :

C

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut temps de calculs très bizarre
    Bonjour, je me suis fait une structure Matrix comme suit

    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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    typedef struct t_mat
    {
        unsigned int nl; // nombre de lignes
        unsigned int nc; // nombre de colonnes
        double ** data;
    } Matrix;
     
     
     
    Matrix * CreateMatrix(unsigned int nl_,unsigned int nc_,double val)
    {
    /* memory allocation */
     
        Matrix * m=malloc(sizeof(*m));
        if(m==NULL)
        {
          MEMERROR;
          exit(EXIT_FAILURE);
        }
     
    /* an empty matrix is defined by nl==0, nc==0 and data==NULL */
        if(nl_==0)
          if(nc_!=0)
          {
            fprintf (stderr,"%s %d : Error : nc_ must be equal to 0\n",__FILE__,__LINE__);
    	    exit(EXIT_FAILURE);	
          }
     
        if(nc_==0)
          if(nl_!=0)
          {
            fprintf (stderr,"%s %d : Error : nl_ must be equal to 0\n",__FILE__,__LINE__);
    		exit(EXIT_FAILURE);	
          }
     
        if(nl_==0)
        {
    	m->nl=0;
    	m->nc=0;
    	m->data=NULL;
        }
        else
        {
    	m->nl=nl_;
    	m->nc=nc_;
    	m->data=malloc(nl_*sizeof(realtype *));
    	if(m->data==NULL)
            {
              MEMERROR;
              exit(EXIT_FAILURE);
            }
     
    	unsigned int i,j;
    	for(i=0;i<nl_;i++)
    	{
              m->data[i]=malloc(nc_*sizeof(realtype));
    	  if(m->data[i]==NULL)
              {
                MEMERROR;
                exit(EXIT_FAILURE);
              }
    	  for(j=0;j<nc_;j++) /* matrix initialisation */
    	    m->data[i][j]=val;
    	}	
        }
     
        return m;
    }
     
    void DestroyMatrix(Matrix ** m)
    {
        (*m)->nc=0;
        (*m)->nl=0;
     
    /* free memory */
        unsigned int i;
        for(i=0;i<(*m)->nc;i++)
        {
    	if((*m)->data[i]!=NULL)
    	{
    	    free((*m)->data[i]);
    	    (*m)->data[i]=NULL;
    	}
        }
        free((*m)->data); (*m)->data=NULL;
        free(*m); *m=NULL;
    }
    Je me donne 3 matrices 1000*1000 (mat1, mat2 et mat3) remplies uniquement de 1. Lorsque j'effectue l'opération mat1*mat2 le temps d'exécution fait 0.62 s mais lorsque je fais mat3=mat1*mat2 le temps d'exécution passe à 16.79 s. Ca me paraît très bizarre... Savez-vous pourquoi ?

    Voici le code pour faire mat1*mat2

    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
     
    int main(int argc,char * argv[])
    { 
      Matrix * mat1=CreateMatrix(1000,1000,1);
      Matrix * mat2=CreateMatrix(1000,1000,1);
      double somme;
      unsigned i,jj;
     
      for(i=0;i<1000;++i)
      {
        for(jj=0;jj<1000;jj++)
        {
          somme=0.;
          for(k=0;k<1000;++k)
           somme+=mat1->data[i][k]*mat2->data[k][jj];
        }
      }
     
      DestroyMatrix(&mat1);
      DestroyMatrix(&mat2);
     
      return 0;
    }
    et voici le code pour faire mat3=mat1*mat2

    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
     
    int main(int argc,char * argv[])
    { 
      Matrix * mat1=CreateMatrix(1000,1000,1);
      Matrix * mat2=CreateMatrix(1000,1000,1);
      Matrix * mat3=CreateMatrix(1000,1000,1);
      double somme;
      unsigned i,jj;
     
      for(i=0;i<1000;++i)
      {
        for(jj=0;jj<1000;jj++)
        {
          somme=0.;
          for(k=0;k<1000;++k)
           somme+=mat1->data[i][k]*mat2->data[k][jj];
     
          mat3->data[i][jj]=somme;
        }
      }
     
      DestroyMatrix(&mat1);
      DestroyMatrix(&mat2);
      DestroyMatrix(&mat3);
     
      return 0;
    }
    Merci.

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    On multiplie beaucoup les matrices en ce moment. Pour ton problème de temps, il se peut qu'il soit du genre évoqué au message suivant, sinon je ne vois pas.
    http://www.developpez.net/forums/sho...d.php?t=329357

    Par ailleurs, ceci ne va pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void DestroyMatrix(Matrix ** m)
    {
        (*m)->nc=0;
        (*m)->nl=0;
     
    /* free memory */
        unsigned int i;
        for(i=0;i<(*m)->nc;i++)
    ....

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    A moins que ton compilateur soit un malin et qu'il se soit aperçu que comme tu ne faisais rien avec prov dans le premier cas, il pouvait largement optimiser et supprimer le calcul

  4. #4
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par diogene
    A moins que ton compilateur soit un malin et qu'il se soit aperçu que comme tu ne faisais rien avec prov dans le premier cas, il pouvait largement optimiser et supprimer le calcul
    +1, c'est clairement cela...

  5. #5
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    A mon avis la fonction CreateMatrix contient des conditions inutiles.

    La mesure du temps d'exécution dans la multiplication des matrices où se trouve-t-elle ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Matrix * m=malloc(sizeof(*m));
    Je voyais plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Matrix * m=malloc(sizeof(Matrix));
    Mais je peux me tromper...

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    La première écriture est meilleure, car plus souple en cas de changement du type pointé par m.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Citation Envoyé par diogene
    A moins que ton compilateur soit un malin et qu'il se soit aperçu que comme tu ne faisais rien avec prov dans le premier cas, il pouvait largement optimiser et supprimer le calcul
    oups... qu'est-ce que prov ?

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Citation Envoyé par diogene
    On multiplie beaucoup les matrices en ce moment. Pour ton problème de temps, il se peut qu'il soit du genre évoqué au message suivant, sinon je ne vois pas.
    http://www.developpez.net/forums/sho...d.php?t=329357

    Par ailleurs, ceci ne va pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void DestroyMatrix(Matrix ** m)
    {
        (*m)->nc=0;
        (*m)->nl=0;
     
    /* free memory */
        unsigned int i;
        for(i=0;i<(*m)->nc;i++)
    ....
    ouhh la boulette ! Merci bcp de ta remarque !

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Citation Envoyé par dj.motte
    Salut,

    A mon avis la fonction CreateMatrix contient des conditions inutiles.

    La mesure du temps d'exécution dans la multiplication des matrices où se trouve-t-elle ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Matrix * m=malloc(sizeof(*m));
    Je voyais plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Matrix * m=malloc(sizeof(Matrix));
    Mais je peux me tromper...
    lorsque je lançais mon programme, je faisais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    time -p mon_executable

  10. #10
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    oups... qu'est-ce que prov ?
    C'est en fait somme dans ton code, celui qui sert de tampon intermédiaire pour le calcul . Je ne sais pas où j'ai été chercher qu'il s'appelait prov

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    OK d'accord. Donc j'en déduis que j'ai un compilo super bien. J'avais compilé avec les options suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CFLAGS=-Wall -W -O2 -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Werror-implicit-function-declaration -Wmain -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings -Wconversion -Wsign-compare -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long -Wunreachable-code

  12. #12
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Par contre, va voir la discussion dont j'ai donné le lien. Selon la manière de faire le produit, le temps peut prendre un facteur 5

  13. #13
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dj.motte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Matrix * m=malloc(sizeof(*m));
    Je voyais plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Matrix * m=malloc(sizeof(Matrix));
    Ces écritures sont sémantiquement identiques. Ca été expliqué dix mille fois. Tu n'écoutes rien, tu ne retiens rien, c'est désespérant...

    La première (parenthèses inutiles) est recommandée, car plus facile à maintenir. De plus, par son écriture régulière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     T *p = malloc (n * sizeof *p);
    elle évite bien des erreurs de codage.

    http://emmanuel-delahaye.developpez....tes.htm#malloc

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Citation Envoyé par diogene
    Par contre, va voir la discussion dont j'ai donné le lien. Selon la manière de faire le produit, le temps peut prendre un facteur 5
    Re,
    en fait, je me suis amusé à chronométrer un produit de matrice 1000*1000 non par hasard mais parce que j'avais déjà lu le post que tu m'as indiqué et j'avais envie de savoir si j'obtenais les mêmes résultats que le posteur (afransisco). Mais j'en suis encore loin... et j'ai une indirection en moins que lui...

    Au début (lorsque je faisais du C++), j'avais une structure matrice du style

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef strcut
    {
      unsigned nbcol,nbrow;
      double * tab;
    } Matrix
    et donc j'accédais à l'élément (i,j) en faisant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    mat->tab[i*nbcol+j];
    certes, il y a une indirection en moins mais il y a deux calculs en plus (i*nbcol+j)... et j'avais donc trouvé qu'il étais plus rapide de faire ce que je faisais.

Discussions similaires

  1. temps d'exécution trop long trés bizarre
    Par fatjoe dans le forum C++
    Réponses: 0
    Dernier message: 09/05/2008, 02h42
  2. Temps de calcul avec deux écrans
    Par Shaga dans le forum OpenGL
    Réponses: 2
    Dernier message: 14/11/2005, 09h24
  3. Problème très bizarre avec COUNT
    Par Nomade95000 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 13/10/2005, 14h12
  4. temps de calculs extremement long !!
    Par salseropom dans le forum C++
    Réponses: 9
    Dernier message: 19/01/2005, 20h12
  5. Réponses: 4
    Dernier message: 28/09/2002, 00h00

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