[C] Vous voyez une erreur d'algo dans ce programme de calcul en // ?

Vous voyez une erreur d'algo dans ce programme de calcul en // ? [C] - C++ - Programmation

Marsh Posté le 02-03-2003 à 21:08:25    

Bonjour,
 
Je dois faire un programme basique, prenant une matrice carree, un vecteur, et calculant le vecteur resultant du produit des deux, le tout sur 4 procos.
 
Pour le vecteur, on nous a oblige a utiliser broadcast, pour la matrice, send/receive. Je sais que ce dernier est VRAIMENT pas optimal, mais c'est ce qu'on nous a demande :/
 
Mon souci est que mon programme est, tenez vous bien, plus rapide en termes de temps d'execution pour calculer une matrice 128x128 qu'une matrice 16x16...
 
Je parle pas de speedup, mais bien de temps d'execution...
 
Et ca me semble vraiment impossible... quelqu'un peux confirmer que j'ai pas fait de connerie ?
 

Code :
  1. include "mpi.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stddef.h> /* defines NULL */
  5. #include <sys/time.h>/* definition of timeval struct and protyping of gettimeofday */
  6. int main (argc,argv)
  7.      int argc;
  8.      char *argv[];
  9. {
  10.   int numprocs = 4;
  11.   int rowperproc = 32;
  12.   int n=128;
  13.   int myid;
  14.   float r;
  15.   int s;
  16.   int i,j,k;
  17.   MPI_Status status;
  18.   double t1,t2,elapsed;
  19.   struct timeval tp;
  20.   int rtn;
  21.   MPI_Init(&argc,&argv);
  22.   MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  23.   MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  24.   if (myid == 0)
  25.     {
  26.       float data[4][32][128];
  27.       float x0[128];
  28.       float x1[4][32];
  29.       //initialising the array
  30.       for(i=0;i<numprocs;i++)
  31.         for(j=0;j<rowperproc;j++)
  32.           x1[i][j]=0.0;
  33.       //create the random numbers
  34.       srand((unsigned)time(NULL));
  35.       for(i=0;i<numprocs;i++)
  36.         for (j=0;j<rowperproc;j++)
  37.           for (k=0;k<n;k++)
  38.           {
  39.             r = (float) random() / (float) 0x7fffffff;
  40.             s = random() %2;
  41.             if (s ==0)
  42.               r *= -1.0;
  43.             data[i][j][k]=r;
  44.             //printf("nb genere : %f\n", r*s);
  45.           }
  46.       for (i=0;i<n;i++)
  47.         {
  48.           r = (float) random() / (float) 0x7fffffff;
  49.           s = random() %2;
  50.           if (s ==0)
  51.             r *= -1.0;
  52.           x0[i]=r;
  53.           //printf("nb genere : %f\n", r);
  54.         }
  55.       //sending the tables to all processors
  56.       for (i=1;i<numprocs;i++)
  57.         {
  58.           MPI_Send(data[i],rowperproc*n,MPI_FLOAT,i,0,MPI_COMM_WORLD);
  59.           // MPI_Send(x0,n,MPI_FLOAT,i,0,MPI_COMM_WORLD);
  60.         }
  61.       MPI_Bcast(x0,n,MPI_FLOAT,0,MPI_COMM_WORLD);
  62.       //Here everybody has the data. Thus, we can start the timer. Cool.
  63.       rtn=gettimeofday(&tp, NULL);
  64.       t1=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
  65.       //Done sending. Now calculating our own sum
  66.       for (j=0;j<rowperproc;j++)
  67.         for(k=0;k<n;k++)
  68.           {
  69.             x1[0][j] += data[0][j][k] * x0[k];
  70.           }
  71.       //Done calculating. Now receiving the results, and finally adding them to our sum
  72.       for (i=1;i<numprocs;i++)
  73.         {
  74.           MPI_Recv(x1[i],rowperproc,MPI_FLOAT,i,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
  75.         }
  76.       rtn=gettimeofday(&tp, NULL);
  77.       t2=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
  78.       elapsed=t2-t1;
  79.       printf("ELAPSED TIME : %f\n",elapsed);
  80.     }
  81.   else
  82.     {
  83.       float myx1[32];
  84.       float data[32][128];
  85.       float x0[128];
  86.       //initialising the array
  87.       for (i=0;i<rowperproc;i++)
  88.         myx1[i]=0.0;
  89.       //waiting to receive our data
  90.       MPI_Recv(data,rowperproc*n,MPI_FLOAT,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
  91.       MPI_Bcast(x0,n,MPI_FLOAT,0,MPI_COMM_WORLD);
  92.       //got it, now we calculate  the result
  93.       for (i=0;i<rowperproc;i++)
  94.         for(j=0;j<n;j++)
  95.           {
  96.             myx1[i] += data[i][j]*x0[j];
  97.           }
  98.       // and we send it back
  99.       MPI_Send(&myx1,rowperproc,MPI_FLOAT,0,1,MPI_COMM_WORLD);
  100.     }
  101.   MPI_Finalize();
  102.   return 0;
  103. }


 
Je sais que mes tableaux sont pas beaux mais spa le probleme la :D
 
Ce que je fais, c'est qu'u lieu de dire que j'ai une matrice de 128x128 par exemple, j'ai une matrice de 4x32x128 , ce qui me permet de diviser le tout assez facilement pour l'envoi etc.
 
Voila la version "serie" de l'algo :
 

Code :
  1. include "mpi.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stddef.h>      /* definition of NULL */
  5. #include <sys/time.h>   /* definition of timeval struct and protyping of gettimeofday */
  6. void print_mat(mat, nbi, nbj)
  7.      float mat[64][64];
  8.      int nbi;
  9.      int nbj;
  10. {
  11.   int i,j,k;
  12.   for (i=0;i<nbi;i++)
  13.     for (j=0;j<nbj;j++)
  14.       {
  15.         printf(" %f", mat[i][j]);
  16.       }
  17.   printf("\n" );
  18. }
  19. void print_x(x,nb)
  20.      float x[64];
  21.      int nb;
  22. {
  23.   int i;
  24.   for (i=0;i<nb;i++)
  25.     printf( " %f",x[i]);
  26.   printf("\n" );
  27. }
  28. int main (argc,argv)
  29.      int argc;
  30.      char *argv[];
  31. {
  32.   int n=64;
  33.   float r;
  34.   int s;
  35.   int i,j,k;
  36.   float data[64][64];
  37.   float x0[64];
  38.   float x1[64];
  39.   double t1,t2,elapsed;
  40.   struct timeval tp;
  41.   int rtn;
  42.   printf("let's go\n" );
  43.   //create the random numbers
  44.   srand((unsigned)time(NULL));
  45.   for(i=0;i<n;i++)
  46.     for (j=0;j<n;j++)
  47.         {
  48.           r = (float) random() / (float) 0x7fffffff;
  49.           s = random() %2;
  50.           if (s ==0)
  51.             r *= -1.0;
  52.           data[i][j]=r;
  53.         }
  54.   for (i=0;i<n;i++)
  55.     {
  56.       r = (float) random() / (float) 0x7fffffff;
  57.       s = random() %2;
  58.       if (s ==0)
  59.         r *= -1.0;
  60.       x0[i]=r;
  61.       //printf("nb genere : %f\n", r);
  62.     }
  63.   //initialising the array
  64.   for(i=0;i<n;i++)
  65.       x1[i]=0.0;
  66.   //data generated. We start the timer. gogogo.
  67.   rtn=gettimeofday(&tp, NULL);
  68.   t1=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
  69.   //calculating
  70.   for (i=0;i<n;i++)
  71.     for(j=0;j<n;j++)
  72.       {
  73.         x1[i] = x1[i] + (data[i][j] * x0[j]);
  74.       }
  75.   rtn=gettimeofday(&tp, NULL);
  76.   t2=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
  77.   elapsed=t2-t1;
  78.   printf("ELAPSED TIME %f\n",elapsed);
  79.   return 0;
  80. }


 
Je sais qu'il fait une matrice de 64x64, mais lui il tourne bieng et j'ai deja ses resultats... c'est pas pour lui qu'il y a le souci.
 
Merci :hello:
 
 

Reply

Marsh Posté le 02-03-2003 à 21:08:25   

Reply

Marsh Posté le 02-03-2003 à 23:31:00    

J'ai pas regardé si il y a des bugs dans ton code, mais le fait que tu observes un gros ralentissement avec la version parallèle ne m'étonne pas du tout. A vrai dire je suis même surpris que la version séquentielle ne te renvoie pas un temps égal à zéro (étant donné que l'horloge a une précision de 1/100ème de sec).
 
Tout ça pour dire que le produit d'une matrice 128x128 avec un vecteur ça doit prendre un millième de seconde sur une grosse bouse. Le temps que tu mesures, c'est le temps du reste du code.
 
Si tu veux avoir des infos pertinentes, commence par mesurer le temps pour faire 1000 produits matrice-vecteur. Et essaye avec des tailles de matrices plus importantes. Et tache de faire tes tests sur une grosse bouse (une bonne vieille sparc quadri-proc à 60MHz par ex), pas un bi-athlon à 2Ghz :D

Reply

Marsh Posté le 03-03-2003 à 00:09:17    

J'ai acces a un cluster de 200 P4 xeon 2Ghz... mais la n'estpas la question.
 
La ou je me pose des questions, c'est pourquoi ca prends plus de temps a faire une matrice 16x16 qu'une matrice 128x128 ?
 
:|
 
C'est le sujet qui est comme ca, une seule multiplication de matrice carree...
 
et je peux pas aller au dela de 1024x10249 limitation compilateur).

Reply

Marsh Posté le 03-03-2003 à 00:19:29    

tetedeiench a écrit :

J'ai acces a un cluster de 200 P4 xeon 2Ghz... mais la n'estpas la question.
 
La ou je me pose des questions, c'est pourquoi ca prends plus de temps a faire une matrice 16x16 qu'une matrice 128x128 ?
 
:|
 
C'est le sujet qui est comme ca, une seule multiplication de matrice carree...
 
et je peux pas aller au dela de 1024x10249 limitation compilateur).


 
- si tu reserve ta matrice avec un malloc, t'auras pas cette limite
- comme je disais plus haut, tu ne mesures le temps d'un calcul qui dure moins d'un millième de secondes avec une horloge qui n'est précise qu'au centième de secondes. Donc mesure le temps de 1000 multiplications et divise ce temps par mille. c'est tout.
 

Reply

Marsh Posté le 03-03-2003 à 00:24:40    

je peux pas faire le calcul 1000 fois malheureusement...  
 
spa dans le sujet ;) et il va m'aligner je pense.
 
Pour la resolution j'y avait pense, mais je devrais obtenir un truc plus coherent nan ?
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed