Tetedeiench Head Of God | 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 :
- include "mpi.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <stddef.h> /* defines NULL */
- #include <sys/time.h>/* definition of timeval struct and protyping of gettimeofday */
- int main (argc,argv)
- int argc;
- char *argv[];
- {
- int numprocs = 4;
- int rowperproc = 32;
- int n=128;
- int myid;
- float r;
- int s;
- int i,j,k;
- MPI_Status status;
- double t1,t2,elapsed;
- struct timeval tp;
- int rtn;
- MPI_Init(&argc,&argv);
- MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
- MPI_Comm_rank(MPI_COMM_WORLD, &myid);
- if (myid == 0)
- {
- float data[4][32][128];
- float x0[128];
- float x1[4][32];
- //initialising the array
- for(i=0;i<numprocs;i++)
- for(j=0;j<rowperproc;j++)
- x1[i][j]=0.0;
- //create the random numbers
- srand((unsigned)time(NULL));
- for(i=0;i<numprocs;i++)
- for (j=0;j<rowperproc;j++)
- for (k=0;k<n;k++)
- {
- r = (float) random() / (float) 0x7fffffff;
- s = random() %2;
- if (s ==0)
- r *= -1.0;
- data[i][j][k]=r;
- //printf("nb genere : %f\n", r*s);
- }
- for (i=0;i<n;i++)
- {
- r = (float) random() / (float) 0x7fffffff;
- s = random() %2;
- if (s ==0)
- r *= -1.0;
- x0[i]=r;
- //printf("nb genere : %f\n", r);
- }
- //sending the tables to all processors
- for (i=1;i<numprocs;i++)
- {
- MPI_Send(data[i],rowperproc*n,MPI_FLOAT,i,0,MPI_COMM_WORLD);
- // MPI_Send(x0,n,MPI_FLOAT,i,0,MPI_COMM_WORLD);
- }
- MPI_Bcast(x0,n,MPI_FLOAT,0,MPI_COMM_WORLD);
- //Here everybody has the data. Thus, we can start the timer. Cool.
- rtn=gettimeofday(&tp, NULL);
- t1=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
- //Done sending. Now calculating our own sum
- for (j=0;j<rowperproc;j++)
- for(k=0;k<n;k++)
- {
- x1[0][j] += data[0][j][k] * x0[k];
- }
- //Done calculating. Now receiving the results, and finally adding them to our sum
- for (i=1;i<numprocs;i++)
- {
- MPI_Recv(x1[i],rowperproc,MPI_FLOAT,i,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
- }
- rtn=gettimeofday(&tp, NULL);
- t2=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
- elapsed=t2-t1;
- printf("ELAPSED TIME : %f\n",elapsed);
- }
- else
- {
- float myx1[32];
- float data[32][128];
- float x0[128];
- //initialising the array
- for (i=0;i<rowperproc;i++)
- myx1[i]=0.0;
- //waiting to receive our data
- MPI_Recv(data,rowperproc*n,MPI_FLOAT,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
- MPI_Bcast(x0,n,MPI_FLOAT,0,MPI_COMM_WORLD);
- //got it, now we calculate the result
- for (i=0;i<rowperproc;i++)
- for(j=0;j<n;j++)
- {
- myx1[i] += data[i][j]*x0[j];
- }
- // and we send it back
- MPI_Send(&myx1,rowperproc,MPI_FLOAT,0,1,MPI_COMM_WORLD);
- }
- MPI_Finalize();
- return 0;
- }
|
Je sais que mes tableaux sont pas beaux mais spa le probleme la
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 :
- include "mpi.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <stddef.h> /* definition of NULL */
- #include <sys/time.h> /* definition of timeval struct and protyping of gettimeofday */
- void print_mat(mat, nbi, nbj)
- float mat[64][64];
- int nbi;
- int nbj;
- {
- int i,j,k;
- for (i=0;i<nbi;i++)
- for (j=0;j<nbj;j++)
- {
- printf(" %f", mat[i][j]);
- }
- printf("\n" );
- }
- void print_x(x,nb)
- float x[64];
- int nb;
- {
- int i;
- for (i=0;i<nb;i++)
- printf( " %f",x[i]);
- printf("\n" );
- }
- int main (argc,argv)
- int argc;
- char *argv[];
- {
- int n=64;
- float r;
- int s;
- int i,j,k;
- float data[64][64];
- float x0[64];
- float x1[64];
- double t1,t2,elapsed;
- struct timeval tp;
- int rtn;
- printf("let's go\n" );
- //create the random numbers
- srand((unsigned)time(NULL));
- for(i=0;i<n;i++)
- for (j=0;j<n;j++)
- {
- r = (float) random() / (float) 0x7fffffff;
- s = random() %2;
- if (s ==0)
- r *= -1.0;
- data[i][j]=r;
- }
- for (i=0;i<n;i++)
- {
- r = (float) random() / (float) 0x7fffffff;
- s = random() %2;
- if (s ==0)
- r *= -1.0;
- x0[i]=r;
- //printf("nb genere : %f\n", r);
- }
- //initialising the array
- for(i=0;i<n;i++)
- x1[i]=0.0;
- //data generated. We start the timer. gogogo.
- rtn=gettimeofday(&tp, NULL);
- t1=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
- //calculating
- for (i=0;i<n;i++)
- for(j=0;j<n;j++)
- {
- x1[i] = x1[i] + (data[i][j] * x0[j]);
- }
- rtn=gettimeofday(&tp, NULL);
- t2=(double)tp.tv_sec+(1.e-6)*tp.tv_usec;
- elapsed=t2-t1;
- printf("ELAPSED TIME %f\n",elapsed);
- return 0;
- }
|
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
|