Partage
  • Partager sur Facebook
  • Partager sur Twitter

Temps de calcul C

    10 septembre 2018 à 18:30:09

    Bonjour,
    J'ai une fonction codé en C qui permet de générer un tableau 3D. Cette fonction génère le grand pourcentage du temps de l'exécution de tout le programme.
    La même fonction a été codé sous Matlab et le temps de calcul est beaucoup moins inférieur, malgré que normalement le C est plus rapide que Matlab.
    Est-ce que vous pensez que normale ou bien je n’ai pas bien codé la fonction?

     
    void matrice_F(float ***F,int M,int N, int O)
    {
    	   float ***Mt=alloue_tableau(vs,vs,s);
            matrice_Mt(Mt,vs,vs,s);
     
     
         float **P=alloue_mtrice(vs,vs);
         matrice_Mr(P,vs,vs);
     
     
        int i,j,k;   
           for (k = 0; k < O; k++)
     
        {
            for (i = 0; i < M; i++)
            {
    			for (j = 0; j < N; j++)
                 {   
     
    				 if (k<dv)
                       {
    		   flash[i][j][k]=0;
    	               }
    	             else
    	               {
     
            F[i][j][k]=(2*Q)/(E*sqrt(pow(M_PI,3)*Mt[i][j][k]))*(1/(pow(R,2)+8*D*Mt[i][j][k]))*exp((-2*pow(P[i][j],2))/(pow(R,2)+8*D*Mt[i][j][k]));
     
    	               }
                }
           }
       }
       	libre_tab(Mt,vs,vs);
       	libre_matrice(P);
    }
     

    Merci

    • Partager sur Facebook
    • Partager sur Twitter
      10 septembre 2018 à 22:41:45

      Bonjour, peux tu fournir le code "Matlab" pour comparer ?
      • Partager sur Facebook
      • Partager sur Twitter
        11 septembre 2018 à 13:47:22

        Salut,

        Plusieurs optimisations :

        - allocation d'un tableau a 3 dimensions, si la matrice est grosse, tu plombes tes performances.

        Fait un seul tableau, quit a te faire une macro pour accéder aux éléments x,y,z 

        #define ELEM(M,X,Y) ((X*M)+Y)
        
        
        float* matrice = malloc(M*N*sizeof(float)); // 1 seul malloc
        
        matrice(ELEM(M,0,0)) = 5.0f;
        
        
        free(matrice);


        Ensuite, pow(machin,2), NON. on fait machin*machin (fait une macro au besoin), car pow permet de faire des puissance flottantes.

        - surtout, je vois des pow(PI,3), donc un invariant, calculé dans la boucle. Calcule le une fois pour toutes, hors du for.

        Pareil pour ton pow(R,2);

        Enfin, quel compilo utilises tu ? Es tu en debug ou en release ? (pour la phase de conception, on est en debug, et quand on veut lancer à fond, on passe en release)

        • Partager sur Facebook
        • Partager sur Twitter

        Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

          11 septembre 2018 à 15:15:09

          un autre truc pour de l'optimisation, il vaut mieux éviter l'appel à des fonctions, car ça demande d'ajouter le contexte à la pile avant d'entrer dans la fonction puis de retirer le contexte de cette même pile en sortant de la fonction et ça c'est très long.

           F[i][j][k]=(2*Q)/(E*sqrt(pow(M_PI,3)*Mt[i][j][k]))*(1/(pow(R,2)+8*D*Mt[i][j][k]))*exp((-2*pow(P[i][j],2))/(pow(R,2)+8*D*Mt[i][j][k]));

          dans cette ligne tu fais appel à six fonctions, c'est un temps de calcul, très long.

          C veux pas dire que ce sera optimisé, C veux dire que ça peut être optimisé, mais seulement si c'est bien écrit :D.

          Si tu veux voir le profil d'exécution de ton code regarde gprof

          • Partager sur Facebook
          • Partager sur Twitter

          la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

          Mon GitHub

            11 septembre 2018 à 15:18:17

            Bonjour,

            Merci Fvirtman pour votre réponse 

            J'utilise MinGW (gcc) comme complo. j'ai pas  trop compris ce que voulez dire par debug ou en release.

            Concrètement j'ai compris "Fait un seul tableau, quit a te faire une macro pour accéder aux éléments x,y,z " est ce que tu peux m'expliquer un peu plus dans mon cas comment je fait.

            Merci

            • Partager sur Facebook
            • Partager sur Twitter
              11 septembre 2018 à 15:59:41

              pour faire un seul tableaux :
              // objectif : table [ 5 ][ 6 ][ 7 ]
              int *table;
              int **table2;
              int ***table3;
              
              table = malloc ( sizeof ( int ) * 5 * 6 * 7 );
              
              table2 = malloc ( sizeof ( int* ) * 5 * 6 );
              for ( int i = 0; i < 5 * 6; i++ )
              {
                  table2[ i ] = &table[ i * 7 ];
              }
              
              table3 = malloc ( sizeof( int** ) * 5 );
              for ( int i = 0; i < 5; i++ )
              {
                  table[ i ] = &table2[ i * 6 * 7 ];
              }
              
              // table3[ 0 ][ 0 ][ 0 ] == table[ 0 ];
              // table3[ 0 ][ 1 ][ 0 ] == table[ 7 ];
              // table3[ 1 ][ 0 ][ 0 ] == table[ 42 ];
              
              
              free ( table );
              free ( table2 );
              free ( table3 );
              

              avec ça tu as une seule zone memoire, mais tu peux y accerder comme un tableau 1D ou 2D ou 3D.

              Ensuite pour le mode release ou debug, c'est dans les option de ton compilo, tu peux demander des optimisation -O0, -O1, O2, O3 ou au contraire tu peux lui demander de rajouter dans le binaire des éléments utilisable pour le debug.

              -
              Edité par ox223252 11 septembre 2018 à 16:00:27

              • Partager sur Facebook
              • Partager sur Twitter

              la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

              Mon GitHub

                13 septembre 2018 à 15:03:57

                Bonjour,

                @ox223252 merci pour votre réponse 

                Après avoir fait les optimisations possible, j'aimerai bien savoir comment je peux demander l'optimisation -O3 avec le compilateur GCC? Avez-vous un doc utile, j'ai trouvé pas mal d'explications théoriques mais je me demande comment je peut mettre en œuvre ces optimisations.

                Merci
                • Partager sur Facebook
                • Partager sur Twitter
                  13 septembre 2018 à 15:09:18

                  en fait pour le faire c'est simple :
                  gcc -O3 -o monProg ...
                  pour le doc je n'ai que celle de gcc qui est dispo sur le web
                  • Partager sur Facebook
                  • Partager sur Twitter

                  la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

                  Mon GitHub

                  Temps de calcul C

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown