Partage
  • Partager sur Facebook
  • Partager sur Twitter

Erreur de segmentation - Threads

Anonyme
    20 novembre 2017 à 22:35:34

    Bonjour,

    Je dois réaliser un programme dans le cadre d'un TP à la fac. Je dois générer des tableaux contenant de 1 à N entiers puis calculer une moyenne arithmétique, quadratique et une somme cubique sur les chiffres du tableau. Le but est de le réaliser en séquentiel puis en parallèle et de comparer les temps d'exécution. Mon code pour la partie séquentiel fonctionne et l'affichage des valeurs également. J'ai un problème avec les threads, une erreur de segmentation et je ne vois pas d'ou elle peut venir même si j'ai du mal avec les pointeurs. J'ai mis du code en commentaire pour réduire la complexité mais impossible de trouver donc si quelqu'un a une idée. Merci

    #include <stdlib.h>
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #include <math.h>
    #include <time.h> 
    #include <sys/time.h>
    #include <unistd.h>
    #include <pthread.h>
    
    
    //Structure contenant les parametres pour les threads
    struct parametres
    {
    	int *Tableau;
    	int j;
    };
    
    /* ******************************  Fonctions sequentiels  ********************************************** */
    
    
    //Fonction qui prend un entier j en paramètre et qui renvoie la moyenne arithmétique des entiers de 1 a j
    float MARIT(int N[], int taille, int j)
    {
    	int somme = 0;
    	for(int i = 0 ; i <= j ; i++)
    	{ somme = somme + N[i]; }
    	float moyArit = somme / (j+1);
    	
    	return moyArit;
    }
    
    //Fonction qui prend un entier j en paramètre et qui renvoie la moyenne quadratique des entiers de 1 a j
    float MQUAD(int N[], int taille, int j)
    {
    	int somme = 0;
    	for(int i = 0 ; i <= j ; i++)
    	{ somme = somme + (N[i]*N[i]); }
    	float moyenne = somme / (j+1);
    	float moyQuad = sqrt(moyenne);
    	
    	return moyQuad;
    }
    
    //Fonction qui prend un entier j en paramètre et qui renvoie la somme cubique des entiers de 1 a j
    float SCUB(int N[], int taille, int j)
    {
    	int somCube = 0;
    	for(int i = 0 ; i <= j ; i++)
    	{ somCube = somCube + (N[i]*N[i]*N[i]); }
    
    	return somCube;
    }
    
    
    /* ******************************  Fonctions avec thread    ******************************************* */
    
    //Fonction qui prend un entier j en paramètre et qui renvoie la moyenne arithmétique des entiers de 1 à j
    void *thread_MARIT(void *parametres)
    {
        struct parametres *params = (struct parametres*)parametres;
        double somme = 0, *resMoyArit;
        for(int i = 0 ; i <= params->j ; i++)
        { somme = somme + params->Tableau[i]; }
     	float moyArit = somme / ((params->j)+1);
     	
     	*resMoyArit = 0; //moyArit;
        pthread_exit(resMoyArit);
    }
    
    /*void *thread_MQUAD(void *parametres)
    {
        struct parametres *params = (struct parametres*)parametres;
        double somme = 0, *resMoyQuad;
        for(int i = 0 ; i <= params->j ; i++)
        { somme = somme + (params->Tableau[i]*params->Tableau[i]); }
    	float moyenne = somme / ((params->j)+1);
    	float moyQuad = sqrt(moyenne);
    	
    	*resMoyQuad = moyQuad;
        pthread_exit(resMoyQuad);
    }
    
    void *thread_SCUB(void *parametres)
    {
    	struct parametres *params = (struct parametres*)parametres;
    	double somCube = 0, *resCube;
    	for(int i = 0 ; i <= params->j ; i++)
    	{ somCube = somCube + (params->Tableau[i]*params->Tableau[i]*params->Tableau[i]); }
    	printf("je suis dans le thread");
    	*resCube = somCube;
        pthread_exit(resCube);
    }*/
    
    
    /* **************************************************************************************************** */
    /* **************************************************************************************************** */
    
    
    int main(int argc, char* argv[])
    {
    	
    	/* Fichier qui récupère les résultats en séquentiel */
    	FILE* fichierSequentiel = NULL;
    	remove("resultat_sequentiel.txt");
    	fichierSequentiel = fopen("resultat_sequentiel.txt", "w");
    	
    	FILE* fichierParallele = NULL;
    	remove("resultat_parallele.txt");
    	fichierParallele = fopen("resultat_parallele.txt", "w");
    	
    	/* Tableau contenant la moyenne des temps pour 1 à 300 valeurs N */
    	double ResultatMoyenSequentiel[300] = {0};
    	double ResultatMoyenParallele[300] = {0};
    	
    	if (fichierSequentiel != NULL)
        {
        	if(fichierParallele != NULL)
    		{
    			/* Boucle des executions pour affiner les resultats */
    			for( int numExecution = 1; numExecution < 31 ; numExecution++)
    			{
    				/* Boucle pour trouver le temps d'execution avec 'taille_tableau' valeurs */
    				printf("Exececution n° : %d\n", numExecution);
    				for(int taille_tableau = 0 ; taille_tableau < 300 ; taille_tableau++)
    				{
    					int i = 0;
    					srand(time(NULL));
    					int N[taille_tableau];
    					
    					for(int j = 0 ; j < taille_tableau ; j++)
    					{   N[j] = rand()%200 + 1; }
    					
    					/* Execution en sequentiel */
    					clock_t debut;
    					debut = clock();
    				
    					while(i < taille_tableau)
    					{
    						float moyArit = 0, moyQuad = 0, somCube = 0;
    						moyArit = MARIT(N, taille_tableau, i);
    						moyQuad = MQUAD(N, taille_tableau, i);
    						somCube = SCUB(N, taille_tableau, i);
    						i++;
    					}
    					
    					ResultatMoyenSequentiel[taille_tableau] = ResultatMoyenSequentiel[taille_tableau] + (double)(clock () - debut) / CLOCKS_PER_SEC;
    					
    					/* Execution en parallele */
    					
    					pthread_t threadMARIT, threadMQUAD, threadSCUB;
    					double *res_MARIT, *res_MQUAD, *res_SCUB;
    					struct parametres lesParametres;
    					lesParametres.Tableau = N;
    					
    					
    					debut = clock();
    					i = 0;
    					while(i < taille_tableau)
    					{
    						lesParametres.j = i;
    						pthread_create(&threadMARIT, NULL, thread_MARIT, (void *)&lesParametres);	
    						//pthread_create(&threadMQUAD, NULL, thread_MQUAD, (void *)&lesParametres);	
    						//pthread_create(&threadSCUB, NULL, thread_SCUB, (void *)&lesParametres);	
    						
    						i++;
    					}
    					
    					pthread_join(threadMARIT, (void **)&res_MARIT);
    					//pthread_join(threadMQUAD, (void**)&res_MQUAD);
    					//pthread_join(threadSCUB, (void**)&res_SCUB);
    					ResultatMoyenParallele[taille_tableau] = ResultatMoyenParallele[taille_tableau] + (double)(clock () - debut) / CLOCKS_PER_SEC;
    					
    				}
    			}
    			
    			for(int k = 0 ; k < 300 ; k++)
    			{
    				ResultatMoyenSequentiel[k] = ResultatMoyenSequentiel[k] / 30;
    				printf("[Sequentiel] - %d valeurs dans le tableau - Temps d'execution %f \n", k+1, ResultatMoyenSequentiel[k]);
    				fprintf(fichierSequentiel, "%d %f \n", k+1, ResultatMoyenSequentiel[k]);
    			}
    			
    			for(int k = 0 ; k < 300 ; k++)
    			{
    				ResultatMoyenParallele[k] = ResultatMoyenParallele[k] / 30;
    				printf("[Parallele] - %d valeurs dans le tableau - Temps d'execution %f \n", k+1, ResultatMoyenParallele[k]);
    				fprintf(fichierParallele, "%d %f \n", k+1, ResultatMoyenParallele[k]);
    			}
    			
    			fclose(fichierSequentiel);
    			fclose(fichierParallele);
    		}
    		
    			
    		FILE * f;
    		f = popen("gnuplot", "w");
    		fprintf(f, "set xrange [0:350];");
    		fprintf(f, "set yrange [0:0.0004];");
    		fprintf(f, "set xlabel \"Nombre de valeurs N\";");
    		fprintf(f, "set ylabel \"Temps\";");
    		fprintf(f, "plot \"resultat_sequentiel.txt\" with lines lc \"orange\", \"resultat_parallele.txt\" with lines lc \"blue\"\n");
    		fflush(f);
    		sleep(100);
    		pclose(f);
    		return(0);
    	}
    }
    
    
    	
    



    • Partager sur Facebook
    • Partager sur Twitter
      21 novembre 2017 à 9:45:15

      1) taille en paramètre de tes fonctions n'est pas utilisé => Enlève le.

      2) Il faut apprendre à être fainéant.
      Tu as codé les fonctions en séquentiels, réutilise-les !

      //la fonction retourne une valeur !
      void *thread_MARIT(void *data)
      {
       struct parametres *params = (struct parametres*)data;
       MARIT(params->Tableau,j);
      
       return NULL;//renvoie un void* et le pthread exit n'est pas util si le thread se termine de lui-même
      }

      Attention cependant à comment tu retourne la valeur, elle ne doit pas être stocké dans une variable locale à la fonction.
      => segmentation fault garanti

      Tu peux par exemple rajouter un champ "result" dans ta structure en entré.

      -
      Edité par neuneutrinos 21 novembre 2017 à 9:45:56

      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        21 novembre 2017 à 17:34:21

        Merci beaucoup

        J'ai corrigé mon code en suivant tes indications. Je n'ai plus d'erreur. J'ai cependant une question, je suppose que le temps d'exécution pour la partie en séquentiel est plus longue que celle en en parallèle puisqu'il effectue les calculs un par un alors que le parallèle les trois en même temps ?
        Mais je n'obtiens pas du tout ce résultat et ça fait plusieurs heures que je relis mon programme et que je réécris la logique sur papier sans comprendre pourquoi.

        J'obtiens ceci : [Sequentiel] - 300 valeurs dans le tableau - Temps d'execution 0.000314
                                [Parallele] - 300 valeurs dans le tableau - Temps d'execution 0.002421

        Je remets bien le temps à zéro pour le parallèle donc ça ne vient pas de ça mais j'ai essayé de placer les pthread_join a différent endroits sans changements. Après le while me semble etre le meilleur endroit pourtant.

        Merci

        #include <stdlib.h>
        #include <stdio.h>
        #include <ctype.h>
        #include <string.h>
        #include <math.h>
        #include <time.h> 
        #include <sys/time.h>
        #include <unistd.h>
        #include <pthread.h>
        
        
        //Structure contenant les parametres pour les threads
        struct parametres
        {
        	int *Tableau;
        	int j;
        };
        
        /* ******************************  Fonctions sequentiels  ********************************************** */
        
        
        //Fonction qui prend un entier j en paramètre et qui renvoie la moyenne arithmétique des entiers de 1 a j
        float MARIT(int N[], int j)
        {
        	int somme = 0;
        	for(int i = 0 ; i <= j ; i++)
        	{ somme = somme + N[i]; }
        	float moyArit = somme / (j+1);
        	
        	return moyArit;
        }
        
        //Fonction qui prend un entier j en paramètre et qui renvoie la moyenne quadratique des entiers de 1 a j
        float MQUAD(int N[], int j)
        {
        	int somme = 0;
        	for(int i = 0 ; i <= j ; i++)
        	{ somme = somme + (N[i]*N[i]); }
        	float moyenne = somme / (j+1);
        	float moyQuad = sqrt(moyenne);
        	
        	return moyQuad;
        }
        
        //Fonction qui prend un entier j en paramètre et qui renvoie la somme cubique des entiers de 1 a j
        float SCUB(int N[], int j)
        {
        	int somCube = 0;
        	for(int i = 0 ; i <= j ; i++)
        	{ somCube = somCube + (N[i]*N[i]*N[i]); }
        
        	return somCube;
        }
        
        
        /* ******************************  Fonctions avec thread    ******************************************* */
        
        //Fonction qui prend un entier j en paramètre et qui renvoie la moyenne arithmétique des entiers de 1 à j
        void *thread_MARIT(void *data)
        {
         struct parametres *params = (struct parametres*)data;
         MARIT(params->Tableau, params->j);
         
         return NULL;
        }
        
        void *thread_MQUAD(void *data)
        {
         struct parametres *params = (struct parametres*)data;
         MQUAD(params->Tableau, params->j);
         
         return NULL;
        }
        
        void *thread_SCUB(void *data)
        {
         struct parametres *params = (struct parametres*)data;
         SCUB(params->Tableau, params->j);
         
         return NULL;
        }
        
        
        
        /* **************************************************************************************************** */
        /* **************************************************************************************************** */
        
        
        int main(int argc, char* argv[])
        {
        	
        	/* Fichier qui récupère les résultats en séquentiel */
        	FILE* fichierSequentiel = NULL;
        	remove("resultat_sequentiel.txt");
        	fichierSequentiel = fopen("resultat_sequentiel.txt", "w");
        	
        	FILE* fichierParallele = NULL;
        	remove("resultat_parallele.txt");
        	fichierParallele = fopen("resultat_parallele.txt", "w");
        	
        	/* Tableau contenant la moyenne des temps pour 1 à 300 valeurs N */
        	double ResultatMoyenSequentiel[300] = {0};
        	double ResultatMoyenParallele[300] = {0};
        	
        	if (fichierSequentiel != NULL)
            {
            	if(fichierParallele != NULL)
        		{
        			/* Boucle des executions pour affiner les resultats */
        			for( int numExecution = 1; numExecution < 31 ; numExecution++)
        			{
        				/* Boucle pour trouver le temps d'execution avec 'taille_tableau' valeurs */
        				printf("Exececution n° : %d\n", numExecution);
        				for(int taille_tableau = 0 ; taille_tableau < 300 ; taille_tableau++)
        				{
        					int i = 0;
        					srand(time(NULL));
        					int N[taille_tableau];
        					
        					for(int j = 0 ; j < taille_tableau ; j++)
        					{   N[j] = rand()%200 + 1; }
        					
        					/* Execution en sequentiel */
        					clock_t debut;
        					debut = clock();
        				
        					while(i < taille_tableau)
        					{
        						float moyArit = 0, moyQuad = 0, somCube = 0;
        						moyArit = MARIT(N, i);
        						moyQuad = MQUAD(N, i);
        						somCube = SCUB(N, i);
        						i++;
        					}
        					ResultatMoyenSequentiel[taille_tableau] = ResultatMoyenSequentiel[taille_tableau] + (double)(clock() - debut) / CLOCKS_PER_SEC;
        					
        					/* Execution en parallele */
        					
        					pthread_t threadMARIT, threadMQUAD, threadSCUB;
        					double *res_MARIT, *res_MQUAD, *res_SCUB;
        					struct parametres lesParametres;
        					lesParametres.Tableau = N;
        					
        					
        					debut = clock();
        					i = 0;
        					while(i < taille_tableau)
        					{
        						lesParametres.j = i;
        						pthread_create(&threadMARIT, NULL, thread_MARIT, (void *)&lesParametres);	
        						pthread_create(&threadMQUAD, NULL, thread_MQUAD, (void *)&lesParametres);	
        						pthread_create(&threadSCUB, NULL, thread_SCUB, (void *)&lesParametres);	
        						i++;
        					}
        					
        					pthread_join(threadMARIT, NULL);
        					pthread_join(threadMQUAD, NULL);
        					pthread_join(threadSCUB, NULL);
        					ResultatMoyenParallele[taille_tableau] = ResultatMoyenParallele[taille_tableau] + (double)(clock() - debut) / CLOCKS_PER_SEC;
        				
        				}
        			}
        			
        			for(int k = 0 ; k < 300 ; k++)
        			{
        				ResultatMoyenSequentiel[k] = ResultatMoyenSequentiel[k] / 30;
        				printf("[Sequentiel] - %d valeurs dans le tableau - Temps d'execution %f \n", k+1, ResultatMoyenSequentiel[k]);
        				fprintf(fichierSequentiel, "%d %f \n", k+1, ResultatMoyenSequentiel[k]);
        			}
        			
        			for(int k = 0 ; k < 300 ; k++)
        			{
        				ResultatMoyenParallele[k] = ResultatMoyenParallele[k] / 30;
        				printf("[Parallele] - %d valeurs dans le tableau - Temps d'execution %f \n", k+1, ResultatMoyenParallele[k]);
        				fprintf(fichierParallele, "%d %f \n", k+1, ResultatMoyenParallele[k]);
        			}
        			
        			fclose(fichierSequentiel);
        			fclose(fichierParallele);
        		}
        		
        			
        		FILE * f;
        		f = popen("gnuplot", "w");
        		fprintf(f, "set xrange [0:350];");
        		fprintf(f, "set yrange [0:0.0004];");
        		fprintf(f, "set xlabel \"Nombre de valeurs N\";");
        		fprintf(f, "set ylabel \"Temps\";");
        		fprintf(f, "plot \"resultat_sequentiel.txt\" with lines lc \"orange\", \"resultat_parallele.txt\" with lines lc \"blue\"\n");
        		fflush(f);
        		sleep(100);
        		pclose(f);
        		return(0);
        	}
        }
        
        
        	
        



        • Partager sur Facebook
        • Partager sur Twitter
          21 novembre 2017 à 17:38:03

          Un seul temps d'execution...
          Recommence ta mesure et regarde l'écart que tu peux avoir pour une même exécution ;) 

          Test avec un plus grand nombre d'élément (genre 100 000 voir bien plus).
          Et note le résultat.

          • Partager sur Facebook
          • Partager sur Twitter
            22 novembre 2017 à 9:04:07

            Bonjour,

            Ton srand ne doit etre effectué qu'une fois.

            Le for de MARIT SCUB ET MQUAD est mal borné

            Quel est l'interet des boucles while lignes 127 et 147, aucun interet a faire ces instructions en boucle? (Tu te rend compte du nombre de threads crées?)

            -
            Edité par breizhbugs 22 novembre 2017 à 11:10:08

            • Partager sur Facebook
            • Partager sur Twitter
            ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
            Anonyme
              22 novembre 2017 à 23:59:47

              "Un seul temps d'execution...

              Recommence ta mesure et regarde l'écart que tu peux avoir pour une même exécution ;) 

              Test avec un plus grand nombre d'élément (genre 100 000 voir bien plus).
              Et note le résultat."

              => J'ai modifié mon code et j'ai mis 10.000 valeurs. 
              En séquentiel, j'obtiens : 1 valeur - 0.000000 // 1.000 valeurs - 0.000009 // 10.000 valeurs - 0.000086 
              En parallèle, avec 1 valeur - 0.000014 // 1.000 valeurs - 0.000012 // 10.000 valeurs - 0.000040
              Je ne comprends pas pourquoi avec une valeur en parallèle le temps est si élevé, une idée ?

              "Ton srand ne doit etre effectué qu'une fois.

              Le for de MARIT SCUB ET MQUAD est mal borné

              Quel est l'interet des boucles while lignes 127 et 147, aucun interet a faire ces instructions en boucle? (Tu te rend compte du nombre de threads crées?)"

              => J'ai modifié les 3 points que tu as cité.

              Je vous réécris mon code en dessous. En sachant que j'ai un autre soucis, c'est que par moment, j'ai une valeur bien au dessus des autres (genre 3x supérieur au autre mais qui représente toujours un temps très faible) qui fausse la courbe. Je vous joint un screen : https://puu.sh/yrBpC/c5ca25d765.png

              Edit : ou ça : https://puu.sh/yrBGj/0bce771e25.png

              Mon code actuel :

              #include <stdlib.h>
              #include <stdio.h>
              #include <ctype.h>
              #include <string.h>
              #include <math.h>
              #include <time.h>
              #include <sys/time.h>
              #include <unistd.h>
              #include <pthread.h>
               
               
              //Structure contenant les parametres pour les threads
              struct parametres
              {
                  int *Tableau;
                  int j;
              };
               
              /* ******************************  Fonctions sequentiels  ********************************************** */
               
               
              //Fonction qui prend un entier j en paramètre et qui renvoie la moyenne arithmétique des entiers de 1 a j
              float MARIT(int N[], int j)
              {
                  int somme = 0;
                  for(int i = 0 ; i < j ; i++)
                  { somme = somme + N[i]; }
                  float moyArit = somme / (j+1);
                   
                  return moyArit;
              }
               
              //Fonction qui prend un entier j en paramètre et qui renvoie la moyenne quadratique des entiers de 1 a j
              float MQUAD(int N[], int j)
              {
                  int somme = 0;
                  for(int i = 0 ; i < j ; i++)
                  { somme = somme + (N[i]*N[i]); }
                  float moyenne = somme / (j+1);
                  float moyQuad = sqrt(moyenne);
                   
                  return moyQuad;
              }
               
              //Fonction qui prend un entier j en paramètre et qui renvoie la somme cubique des entiers de 1 a j
              float SCUB(int N[], int j)
              {
                  int somCube = 0;
                  for(int i = 0 ; i < j ; i++)
                  { somCube = somCube + (N[i]*N[i]*N[i]); }
               
                  return somCube;
              }
               
               
              /* ******************************  Fonctions avec thread    ******************************************* */
               
              //Fonction qui prend un entier j en paramètre et qui renvoie la moyenne arithmétique des entiers de 1 à j
              void *thread_MARIT(void *data)
              {
               struct parametres *params = (struct parametres*)data;
               MARIT(params->Tableau, params->j);
                
               return NULL;
              }
               
              void *thread_MQUAD(void *data)
              {
               struct parametres *params = (struct parametres*)data;
               MQUAD(params->Tableau, params->j);
                
               return NULL;
              }
               
              void *thread_SCUB(void *data)
              {
               struct parametres *params = (struct parametres*)data;
               SCUB(params->Tableau, params->j);
                
               return NULL;
              }
               
               
               
              /* **************************************************************************************************** */
              /* **************************************************************************************************** */
               
               
              int main(int argc, char* argv[])
              {
                   
                  /* Fichier qui récupère les résultats en séquentiel */
                  FILE* fichierSequentiel = NULL;
                  remove("resultat_sequentiel.txt");
                  fichierSequentiel = fopen("resultat_sequentiel.txt", "w");
                   
                  FILE* fichierParallele = NULL;
                  remove("resultat_parallele.txt");
                  fichierParallele = fopen("resultat_parallele.txt", "w");
                   
                  /* Tableau contenant la moyenne des temps pour 1 à 300 valeurs N */
                  double ResultatMoyenSequentiel[10000] = {0};
                  double ResultatMoyenParallele[10000] = {0};
                  srand(time(NULL));
                   
                  if (fichierSequentiel != NULL)
                  {
                      if(fichierParallele != NULL)
                      {
                          /* Boucle des executions pour affiner les resultats */
                          for( int numExecution = 1; numExecution < 31 ; numExecution++)
                          {
                              /* Boucle pour trouver le temps d'execution avec 'taille_tableau' valeurs */
                              printf("Exececution n° : %d\n", numExecution);
                              for(int taille_tableau = 0 ; taille_tableau < 10000 ; taille_tableau++)
                              {
                                  int i = 0;
                                  int N[taille_tableau];
                                   
                                  for(int j = 0 ; j < taille_tableau ; j++)
                                  {   N[j] = rand()%200 + 1; }
                                   
                                  /* Execution en sequentiel */
                                  clock_t debut;
                                  debut = clock();
                               
                                  
                                  float moyArit = 0, moyQuad = 0, somCube = 0;
                                  moyArit = MARIT(N, taille_tableau);
                                  moyQuad = MQUAD(N, taille_tableau);
                                  somCube = SCUB(N, taille_tableau);
                                  i++;
                                  
                                  ResultatMoyenSequentiel[taille_tableau] = ResultatMoyenSequentiel[taille_tableau] + (double)(clock() - debut) / CLOCKS_PER_SEC;
                                   
                                  /* Execution en parallele */
                                   
                                  pthread_t threadMARIT, threadMQUAD, threadSCUB;
                                  double *res_MARIT, *res_MQUAD, *res_SCUB;
                                  struct parametres lesParametres;
                                  lesParametres.Tableau = N;
                                   
                                   
                                  debut = clock();
                                  
                                  lesParametres.j = taille_tableau;
                                  pthread_create(&threadMARIT, NULL, thread_MARIT, (void *)&lesParametres);  
                                  pthread_create(&threadMQUAD, NULL, thread_MQUAD, (void *)&lesParametres);  
                                  pthread_create(&threadSCUB, NULL, thread_SCUB, (void *)&lesParametres);
                                  
                                   
                                  pthread_join(threadMARIT, NULL);
                                  pthread_join(threadMQUAD, NULL);
                                  pthread_join(threadSCUB, NULL);
                                  ResultatMoyenParallele[taille_tableau] = ResultatMoyenParallele[taille_tableau] + (double)(clock() - debut) / CLOCKS_PER_SEC;
                               
                              }
                          }
                           
                          for(int k = 0 ; k < 10000 ; k++)
                          {
                              ResultatMoyenSequentiel[k] = ResultatMoyenSequentiel[k] / 30;
                              printf("[Sequentiel] - %d valeurs dans le tableau - Temps d'execution %f \n", k+1, ResultatMoyenSequentiel[k]);
                              fprintf(fichierSequentiel, "%d %f \n", k+1, ResultatMoyenSequentiel[k]);
                          }
                           
                          for(int k = 0 ; k < 10000 ; k++)
                          {
                              ResultatMoyenParallele[k] = ResultatMoyenParallele[k] / 30;
                              printf("[Parallele] - %d valeurs dans le tableau - Temps d'execution %f \n", k+1, ResultatMoyenParallele[k]);
                              fprintf(fichierParallele, "%d %f \n", k+1, ResultatMoyenParallele[k]);
                          }
                           
                          fclose(fichierSequentiel);
                          fclose(fichierParallele);
                      }
                       
                           
                    	FILE * f;
                      f = popen("gnuplot", "w");
                      //fprintf(f, "set xrange [0:350];");
                      //fprintf(f, "set yrange [0:0.0004];");
                      fprintf(f, "set xlabel \"Nombre de valeurs N\";");
                      fprintf(f, "set ylabel \"Temps\";");
                      fprintf(f, "plot \"resultat_sequentiel.txt\" with lines lc \"orange\", \"resultat_parallele.txt\" with lines lc \"blue\"\n");
                      fflush(f);
                      sleep(100);
                      pclose(f);
                      return(0);
                  }
              }


               

              -
              Edité par Anonyme 23 novembre 2017 à 0:09:21

              • Partager sur Facebook
              • Partager sur Twitter
                23 novembre 2017 à 0:32:58

                Narvek a écrit:


                float MARIT(int N[], int j)
                {
                    int somme = 0;
                    for(int i = 0 ; i < j ; i++)
                    { somme = somme + N[i]; }
                    float moyArit = somme / (j+1);
                     
                    return moyArit;
                }
                

                moy = somme / j; // pas j+1 car de 0 à j-1 il y a j éléments.
                 

                Un tableau de 10000; ca me semble pas beaucoup et le systeme passe plus de temps a activer un thread (c'est peut être ton pic?)qu'a faire le calcul a mon avis... essai sur 500 000+ valeurs?

                • Partager sur Facebook
                • Partager sur Twitter
                ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
                Anonyme
                  23 novembre 2017 à 9:01:55

                  Juste une petite remarque, car depuis le début du topic cela me titille, mais les fonctions comme MARIT ne sont-elle pas buggé ?

                  Je veux dire, "somme" est un int, "j + 1" est un int, alors "somme / (j + 1)" est une division d'entier, mais pourtant la fonction est censé renvoyer un float.
                  C'est normal ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    23 novembre 2017 à 11:35:43

                    Narvek a écrit:

                    "Un seul temps d'execution...

                    Recommence ta mesure et regarde l'écart que tu peux avoir pour une même exécution ;) 

                    Test avec un plus grand nombre d'élément (genre 100 000 voir bien plus).
                    Et note le résultat."

                    => J'ai modifié mon code et j'ai mis 10.000 valeurs. 

                    Bonjour,

                    Tu codes en C en 2017, pas en Pascal 1997. Testes avec au moins 100 millions de valeurs.

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      23 novembre 2017 à 19:01:29

                      "moy = somme / j; // pas j+1 car de 0 à j-1 il y a j éléments."

                      => Je passe l'indice de la case et non le nombre d'élements. Si dans le main, mon for va de 0 a 299 valeurs et que je peux passe j = 299 dans ma fonction de moyenne, il y a bien 300 valeurs (299 + le 0), non ? 
                      Il y a un commentaire qui m'a dit que le for des fonctions de moyenne était mal borné également. Mais si je passe j=299, pour accéder aux cases de 0 a 299, il faut bien que ma boucle aille de 0 a 299 donc i=0;i<j+1;i++ non ?

                      "Un tableau de 10000; ca me semble pas beaucoup et le systeme passe plus de temps a activer un thread (c'est peut être ton pic?)qu'a faire le calcul a mon avis... essai sur 500 000+ valeurs?"

                      "Bonjour,

                      Tu codes en C en 2017, pas en Pascal 1997. Testes avec au moins 100 millions de valeurs."

                      => Je vais essayer mais le prof veut qu'on l'exécute devant lui donc avant beaucoup de valeurs ça va durer longtemps et je pourrai pas lui montrer le résultat mais pour les tests je vais le faire. Mais ça explique pas le pic puisqu'il apparait a des endroits alétoires apparement

                      "Juste une petite remarque, car depuis le début du topic cela me titille, mais les fonctions comme MARIT ne sont-elle pas buggé ?


                      Je veux dire, "somme" est un int, "j + 1" est un int, alors "somme / (j + 1)" est une division d'entier, mais pourtant la fonction est censé renvoyer un float.
                      C'est normal ?"

                      => Peut etre que j'ai mal compris mais 45(int)/2(int)=27.5(float)


                      Merci pour votre aide en tout cas

                      -
                      Edité par Anonyme 23 novembre 2017 à 19:03:48

                      • Partager sur Facebook
                      • Partager sur Twitter
                        23 novembre 2017 à 22:18:03

                        Bonsoir

                        Narvek a écrit:

                        Tu codes en C en 2017, pas en Pascal 1997. Testes avec au moins 100 millions de valeurs."

                        => Je vais essayer mais le prof veut qu'on l'exécute devant lui donc avant beaucoup de valeurs ça va durer longtemps et je pourrai pas lui montrer le résultat mais pour les tests je vais le faire.

                        Quoi, ton professeur ne peut pas attendre 3 dixièmes de secondes ?
                        Combien de temps imagines-tu qu'il faille pour allouer, initialiser, moyenner, et libérer 100 millions d'entiers?

                        Oui, lorsqu'on divise un int pas un int, on obtient un int par division entière.
                        Cela dit, il y a probablement d'autres bugs dans le code, comme la borne des instructions for.
                        Mais le plus urgent à changer pour y voir clair et ne pas perdre des points sur la lisibilité du code, c'est de renommer le membre de structure 'j' en qqch qui a un sens.

                        -
                        Edité par Marc Mongenet 23 novembre 2017 à 22:26:50

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          23 novembre 2017 à 23:10:29

                          3 dixième de seconde ? J'ai mis 100.000 valeurs et ça me prend déjà plus de 3 minutes

                          Ah autant pour moi pour la division entière, je corrigerais alors.

                          Oui il faut que je change le nom des variables pour que ce soit plus clair

                          • Partager sur Facebook
                          • Partager sur Twitter
                            24 novembre 2017 à 0:26:43

                            Narvek a écrit:

                            3 dixième de seconde ? J'ai mis 100.000 valeurs et ça me prend déjà plus de 3 minutes

                            Sur un processeur actuel, ça fait environ 9 millions d'instructions machine par valeur. Il y a un gros pépin.

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Anonyme
                              24 novembre 2017 à 9:15:37

                              Narvek a écrit:

                              => Peut etre que j'ai mal compris mais 45(int)/2(int)=27.5(float)


                              Non.

                              int main(void)
                              {
                              	float test;
                              
                              	test = 45 / 2;
                              	printf("%f\n", test);
                              
                              	test = 45. / 2;
                              	printf("%f\n", test);
                              
                              	exit(0);
                              }



                              • Partager sur Facebook
                              • Partager sur Twitter
                                24 novembre 2017 à 9:43:20

                                @Marc: Je comprends pas, c'est censé mettre beaucoup moins de temps ? Parce que je fais rien de spécial dans le code donc je vois pas pourquoi ce serait plus long que prévu 

                                @SofEvans2 : D'accord merci, je modifierai tout a l'heure

                                J'ai toujours des pics inexpliqués alors je me suis dis que j'allais afficher la valeur qu'en le graphique uniquement si elle est inférieur au temps de l'an precedente*1,5, vous en pensez quoi ?

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  24 novembre 2017 à 11:09:17

                                  AlexandreLemeret a écrit:

                                  J'ai toujours des pics inexpliqués alors je me suis dis que j'allais afficher la valeur qu'en le graphique uniquement si elle est inférieur au temps de l'an precedente*1,5, vous en pensez quoi ?

                                  rien de bon.
                                  Si c'est un tp c'est pour apprendre et comme dit plus tot c'est peut etre "naturel" (changement de contexte en plein calcul par exemple c'est très couteux)...
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
                                  Anonyme
                                    24 novembre 2017 à 11:12:54

                                    J'en pense que cacher des valeurs parce qu'elle ne te plaise pas n'est vraiment pas une bonne idée.
                                    Ces valeurs existent.

                                    Soit elles sont réelles (programme bon), et cela peut venir de plein de facteur différent.
                                    Soit elles résultent d'un bug, en ce cas, il faut regarder le code.

                                    Je suis en train de reprendre un peu ton code, et le moins qu'on puisse dire, c'est que c'est un sacré bordel !
                                    Ca se voit que tu as empilé petit à petit du code sans vraiment réfléchir au découpage.

                                    Par curiosité, jusqu'à quel point tu es libre dans l'implémentation de ton TP ?
                                    Si par exemple je modifie le prototype des MARIT ?

                                    // original
                                    float MARIT(int N[], int j)
                                    
                                    // Autorisé ?
                                    float MARIT(int array[], size_t size)
                                    
                                    // Autorisé ?
                                    float MARIT(struct parametre *params)


                                    Edit : Typiquement, commencer la boucle for avec taille_tableau = 0 pour ensuite faire "int N[taille_tableau]", ça démontre que c'est un peu fait à l'arrache quand même.

                                    -
                                    Edité par Anonyme 24 novembre 2017 à 11:17:48

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Anonyme
                                      24 novembre 2017 à 11:41:46

                                      breizhbugs a écrit:

                                      AlexandreLemeret a écrit:

                                      J'ai toujours des pics inexpliqués alors je me suis dis que j'allais afficher la valeur qu'en le graphique uniquement si elle est inférieur au temps de l'an precedente*1,5, vous en pensez quoi ?

                                      rien de bon.
                                      Si c'est un tp c'est pour apprendre et comme dit plus tot c'est peut etre "naturel" (changement de contexte en plein calcul par exemple c'est très couteux)...

                                      Oui en effet mais le programme effectue les mêmes calculs à chaque exécution et les "piques" se déplacent, ça pourrait être du au fait que le tableau soit remplis de nombres aléatoires ? Je devrais le remplir avec le même nombre ?
                                      Je m'étais dit qu'en faisait une moyenne des résultats en faisant plusieurs exécutions, j'éviterais ceci mais non et ça augmente beaucoup le temps d’exécution. Il vaudrait mieux mettre plus de valeurs avec une seule voire deux exécutions ou moins de valeurs mais plus d'exécution pour plus de précision ? 

                                      SofEvans2 a écrit:

                                      J'en pense que cacher des valeurs parce qu'elle ne te plaise pas n'est vraiment pas une bonne idée.
                                      Ces valeurs existent.

                                      Soit elles sont réelles (programme bon), et cela peut venir de plein de facteur différent.
                                      Soit elles résultent d'un bug, en ce cas, il faut regarder le code.

                                      Je suis en train de reprendre un peu ton code, et le moins qu'on puisse dire, c'est que c'est un sacré bordel !
                                      Ca se voit que tu as empilé petit à petit du code sans vraiment réfléchir au découpage.

                                      Par curiosité, jusqu'à quel point tu es libre dans l'implémentation de ton TP ?
                                      Si par exemple je modifie le prototype des MARIT ?

                                      // original
                                      float MARIT(int N[], int j)
                                      
                                      // Autorisé ?
                                      float MARIT(int array[], size_t size)
                                      
                                      // Autorisé ?
                                      float MARIT(struct parametre *params)



                                      Oui je me doute mais je me suis dis que vu les très très faibles temps d'exécution peut être qu'un facteur externe minime, genre l'antivirus qui cherche un fichier une seconde, peut fausser des résultats. J'ai remis tous les résultats du coup

                                      Ah ? Je trouvais ça bien organiser avec le main, la séparation séquentiel/parallèle et pareil pour les fonctions. Tu me conseilles de changer quoi ?

                                      Les trois sont autorisés, on fait vraiment comme on veut mais j'aurais plus de mal avec la troisième forme.

                                      --

                                      Désolé pour les messages précédents, j'étais sur téléphone et le correcteur à changé des mots


                                      Edit :

                                      "Edit : Typiquement, commencer la boucle for avec taille_tableau = 0 pour ensuite faire "int N[taille_tableau]", ça démontre que c'est un peu fait à l'arrache quand même."

                                      C'est pas du tout l'impression que je voulais rendre. Je comprends pas comment j'aurais pu faire autrement. Je veux créer un tableau qui suit l'incrémentation de la boucle et qui va donc de 0 à taille_tableau 



                                      -
                                      Edité par Anonyme 24 novembre 2017 à 11:45:01

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Anonyme
                                        24 novembre 2017 à 12:00:35

                                        Tiens, j'ai finis.

                                        Normalement, fonctionnellement, le code identique.
                                        Cependant, comme j'ai codé sans testé, il faut que tu vérifie (et de toute facon, il faut que tu comprennes ce que je fais)

                                        Pour moi, le main est clairement plus compréhensible.
                                        Les deux boucles for tiennent sur moins d'une vingtaine de lignes (sans les printf), ce qui facilite la lecture.

                                        J'ai même réussi à faire un truc sympa avec gnuplot ^^

                                        #include <stdlib.h>
                                        #include <stdio.h>
                                        #include <ctype.h>
                                        #include <string.h>
                                        #include <math.h>
                                        #include <time.h>
                                        #include <sys/time.h>
                                        #include <unistd.h>
                                        #include <pthread.h>
                                        #include <errno.h>
                                        
                                        
                                        #define NB_EXECUTION   30
                                        #define ARRAY_SIZE_MAX 100000
                                        
                                        typedef struct array {
                                        	int    content[ARRAY_SIZE_MAX];
                                        	size_t size;
                                        } array_s;
                                        
                                        void Array_GenerateContent(array_s *self)
                                        {
                                        	for (size_t i = 0; i < self->size; ++i) {
                                        		self->content[i] = rand() % 200 + 1;
                                        	}
                                        }
                                        
                                        /* ******************************  Fonctions sequentiels  ********************************************** */
                                        
                                        float MARIT(array_s *self)
                                        {
                                        	float sum = 0;
                                        
                                        	for (size_t i = 0; i < self->size; i++) {
                                        		sum += self->content[i];
                                        	}
                                        	return  (sum / self->size);
                                        }
                                        
                                        float MQUAD(array_s *self)
                                        {
                                        	float sum = 0;
                                        
                                        	for(size_t i = 0; i < self->size; i++) {
                                        		sum += self->content[i] * self->content[i];
                                        	}
                                        	return (sqrt(sum / self->size));
                                        }
                                        
                                        float SCUB(array_s *self)
                                        {
                                        	float sum = 0;
                                        
                                        	for (size_t i = 0; i < self->size; i++) {
                                        		sum += self->content[i] * self->content[i] * self->content[i];
                                        	}
                                        	return (sum);
                                        }
                                        
                                        double GetSequentialExecutionTime(array_s *array)
                                        {
                                        	clock_t debut = clock();
                                        
                                        	MARIT(array);
                                        	MQUAD(array);
                                        	SCUB(array);
                                        
                                        	return ((double)(clock() - debut) / CLOCKS_PER_SEC);
                                        }
                                        
                                        /* ******************************  Fonctions avec thread    ******************************************* */
                                        
                                        void *thread_MARIT(void *data)
                                        {
                                        	MARIT(data);
                                        
                                        	return NULL;
                                        }
                                        
                                        void *thread_MQUAD(void *data)
                                        {
                                        	MQUAD(data);
                                        
                                        	return NULL;
                                        }
                                        
                                        void *thread_SCUB(void *data)
                                        {
                                        	SCUB(data);
                                        
                                        	return NULL;
                                        }
                                        
                                        double GetParalleleExecutionTime(array_s *array)
                                        {
                                        	pthread_t threadMARIT;
                                        	pthread_t threadMQUAD;
                                        	pthread_t threadSCUB;
                                        	clock_t   debut       = clock();
                                        
                                        	// Il serait bien ici de gerer le cas où la création d'un thread echoue
                                        	pthread_create(&threadMARIT, NULL, thread_MARIT, array);
                                        	pthread_create(&threadMQUAD, NULL, thread_MQUAD, array);
                                        	pthread_create(&threadSCUB, NULL, thread_SCUB, array);
                                        
                                        	pthread_join(threadMARIT, NULL);
                                        	pthread_join(threadMQUAD, NULL);
                                        	pthread_join(threadSCUB, NULL);
                                        
                                        	return ((double)(clock() - debut) / CLOCKS_PER_SEC);
                                        }
                                        
                                        /* **************************************************************************************************** */
                                        /* **************************************************************************************************** */
                                        
                                        int main(void)
                                        {
                                        	FILE    *seqFile = NULL;
                                        	FILE    *parFile = NULL;
                                        	FILE    *plot    = NULL;
                                        	double  timeSeq;
                                        	double  timePar;
                                        	array_s array;
                                        
                                        	srand(time(NULL));
                                        
                                        	// Initialisation du programme
                                        	if (!(seqFile = fopen("resultat_sequentiel.txt", "w"))) {
                                        		fprintf(stderr, "Impossible d'ouvrir le fichier 'resultat_sequentiel.txt'. Erreur = '%s'.\n", strerror(errno));
                                        		return (EXIT_FAILURE);
                                        	}
                                        	if (!(parFile = fopen("resultat_parallele.txt", "w"))) {
                                        		fprintf(stderr, "Impossible d'ouvrir le fichier 'resultat_parallele.txt'. Erreur = '%s'.\n", strerror(errno));
                                        		return (EXIT_FAILURE);
                                        	}
                                        	if (!(plot = popen("gnuplot", "w"))) {
                                        		fprintf(stderr, "Impossible d'ouvrir 'gnuplot'. Erreur = '%s'.\n", strerror(errno));
                                        		return (EXIT_FAILURE);
                                        	}
                                        	fprintf(plot, "set xlabel \"Nombre de valeurs N\";");
                                        	fprintf(plot, "set ylabel \"Temps\";");
                                        	fprintf(plot, "plot \"resultat_sequentiel.txt\" with lines lc \"orange\", \"resultat_parallele.txt\" with lines lc \"blue\"\n");
                                        
                                        
                                        
                                        	for (array.size = 1; array.size < ARRAY_SIZE_MAX; ++array.size) {
                                        		// on remet à zero les compteur
                                        		timeSeq = 0;
                                        		timePar = 0;
                                        		// On génère un tableau
                                        		Array_GenerateContent(&array);
                                        
                                        		/* Boucle des executions pour affiner les resultats */
                                        		for (int execution = 0; execution < NB_EXECUTION; ++execution) {
                                        			timeSeq += GetSequentialExecutionTime(&array);
                                        			timePar += GetParalleleExecutionTime(&array);
                                        		}
                                        		timeSeq /= NB_EXECUTION;
                                        		timePar /= NB_EXECUTION;
                                        
                                        		fprintf(seqFile, "%zu %f \n", array.size, timeSeq);
                                        		fprintf(parFile, "%zu %f \n", array.size, timePar);
                                        
                                        		// Tout les 500 taille de tableau, on rafraichit gnuplot
                                        		if (array.size % 500 == 0) {
                                        			fflush(seqFile);
                                        			fflush(parFile);
                                        			fprintf(plot, "replot\n");
                                        			fflush(plot);
                                        		}
                                        	}
                                        
                                        	fclose(seqFile);
                                        	fclose(parFile);
                                        	sleep(100);
                                        	pclose(plot);
                                        	return (EXIT_SUCCESS);
                                        }
                                        
                                        
                                        





                                        -
                                        Edité par Anonyme 24 novembre 2017 à 14:23:17

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          24 novembre 2017 à 12:04:15

                                          AlexandreLemeret a écrit:

                                          @Marc: Je comprends pas, c'est censé mettre beaucoup moins de temps ? Parce que je fais rien de spécial dans le code donc je vois pas pourquoi ce serait plus long que prévu 

                                          C'est très long car ton code teste avec 1 valeur, puis 2, puis 3, ... jusqu'à 1000000.
                                          Et la somme de 1 à n vaut n * (n + 1) / 2 soit 5000050000 pour n=100000.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Anonyme
                                            24 novembre 2017 à 12:30:09

                                            Le tableau comporte des valeurs aléatoires de [1:200] (les valeurs étant changé à chaque tour de boucle.

                                            Sinon, j'ai exécuté le code est le multithreading est plus lent que la version séquentielle pour ma part.
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                            Anonyme
                                              24 novembre 2017 à 12:43:40

                                              Marc Mongenet a écrit:

                                              AlexandreLemeret a écrit:

                                              @Marc: Je comprends pas, c'est censé mettre beaucoup moins de temps ? Parce que je fais rien de spécial dans le code donc je vois pas pourquoi ce serait plus long que prévu 

                                              C'est très long car ton code teste avec 1 valeur, puis 2, puis 3, ... jusqu'à 1000000.
                                              Et la somme de 1 à n vaut n * (n + 1) / 2 soit 5000050000 pour n=100000.

                                              Oui mais c'est bien ce que je veux, qu'il me donne le temps pour faire la moyenne d'un tableau qui contient 1 chiffre, puis 2 puis 3 jusqu'à n pour voir l'augmentation du temps suivant le nombre de chiffre dans le tableau en séquentiel puis en parallèle donc c'est normal que ce soit long non ?

                                              SofEvans2 a écrit:

                                              Le tableau comporte des valeurs aléatoires de [1:200] (les valeurs étant changé à chaque tour de boucle.

                                              Sinon, j'ai exécuté le code est le multithreading est plus lent que la version séquentielle pour ma part.


                                              Et c'est pas censé être l'inverse ? Je sais que c'est un TP et qu'on doit arriver a une conclusion à partir des résultats et non l'inverse mais j'aurais pensé que faire trois calculs en même temps serait plus rapide que de les faire un par un

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                24 novembre 2017 à 12:45:53

                                                SofEvans2 a écrit:


                                                Sinon, j'ai exécuté le code est le multithreading est plus lent que la version séquentielle pour ma part.


                                                Vu la taille du tableau, c'est pas étonnant: le cout de synchronisation est trop important...

                                                Narvek a écrit:

                                                Marc Mongenet a écrit:

                                                AlexandreLemeret a écrit:

                                                @Marc: Je comprends pas, c'est censé mettre beaucoup moins de temps ? Parce que je fais rien de spécial dans le code donc je vois pas pourquoi ce serait plus long que prévu 

                                                C'est très long car ton code teste avec 1 valeur, puis 2, puis 3, ... jusqu'à 1000000.
                                                Et la somme de 1 à n vaut n * (n + 1) / 2 soit 5000050000 pour n=100000.

                                                Oui mais c'est bien ce que je veux, qu'il me donne le temps pour faire la moyenne d'un tableau qui contient 1 chiffre, puis 2 puis 3 jusqu'à n pour voir l'augmentation du temps suivant le nombre de chiffre dans le tableau en séquentiel puis en parallèle donc c'est normal que ce soit long non ?


                                                Plutot que d'incrementer ton tableau valeur par valeur, fait des bon de 10 000 sur une taille totale de tableau de 1 000 000... la ce sera intéressant.

                                                -
                                                Edité par breizhbugs 24 novembre 2017 à 12:47:56

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                ** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
                                                Anonyme
                                                  24 novembre 2017 à 13:08:35

                                                  breizhbugs a écrit:

                                                  SofEvans2 a écrit:


                                                  Sinon, j'ai exécuté le code est le multithreading est plus lent que la version séquentielle pour ma part.


                                                  Vu la taille du tableau, c'est pas étonnant: le cout de synchronisation est trop important...

                                                  Narvek a écrit:

                                                  Marc Mongenet a écrit:

                                                  AlexandreLemeret a écrit:

                                                  @Marc: Je comprends pas, c'est censé mettre beaucoup moins de temps ? Parce que je fais rien de spécial dans le code donc je vois pas pourquoi ce serait plus long que prévu 

                                                  C'est très long car ton code teste avec 1 valeur, puis 2, puis 3, ... jusqu'à 1000000.
                                                  Et la somme de 1 à n vaut n * (n + 1) / 2 soit 5000050000 pour n=100000.

                                                  Oui mais c'est bien ce que je veux, qu'il me donne le temps pour faire la moyenne d'un tableau qui contient 1 chiffre, puis 2 puis 3 jusqu'à n pour voir l'augmentation du temps suivant le nombre de chiffre dans le tableau en séquentiel puis en parallèle donc c'est normal que ce soit long non ?


                                                  Plutot que d'incrementer ton tableau valeur par valeur, fait des bon de 10 000 sur une taille totale de tableau de 1 000 000... la ce sera intéressant.

                                                  -
                                                  Edité par breizhbugs il y a 19 minutes

                                                  Ahhh oui, c'est une excellente idée, j'y avais pas du tout pensé. Merci !

                                                  --

                                                  @SofEvans2: Je regarde le code en rentrant de cours, merci beaucoup également !

                                                  -
                                                  Edité par Anonyme 24 novembre 2017 à 13:09:52

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  Anonyme
                                                    24 novembre 2017 à 13:10:59

                                                    Narvek a écrit:

                                                    Et c'est pas censé être l'inverse ? Je sais que c'est un TP et qu'on doit arriver a une conclusion à partir des résultats et non l'inverse mais j'aurais pensé que faire trois calculs en même temps serait plus rapide que de les faire un par un


                                                    Pas forcement.

                                                    Le multithreading, ça à un côté "magique", genre tu mets ton code en multi-threading et hop, ca va plus vite.

                                                    Dans la réalité, il y a tellement de chose à prendre en compte qu'on fait du multi-threading s'il le faut et après avoir réflechi.

                                                    La par exemple, l'intêret du multithreading est très limité :

                                                    Pour des tailles de tableau assez basse (genre 10000 avec 30 exécution à chaque fois), le code ne mets même pas 1 seconde ...
                                                    Donc bon ...

                                                    Une idée intéressante serait d'avoir un grand tableau (genre 100 000 000 si la mémoire / OS le permet) et au moment de faire un des trois calcules, de "decouper" le tableau en plus petit tableau, et chaque tableau et envoyé à un thread.
                                                    Si ton tableau fait 100 cases, et que tu fais 4 thread, alors chaque thread ne s'occupe que de 25 cases.

                                                    Bien sûr, il faut que les données soit traitable indépendamment (et c'est le cas pour les 3 fonctions), et il faudrait que le traitement séquentielle prenne du temps, sinon, le coût de création des threads et tout le tutti-quanti (synchro entre autre) reviendrait trop chère.
                                                    C'est d'ailleurs ce qu'il m'arrive quand je test.

                                                    Il faut aussi éviter de se dire "je vais faire plus de thread, ca ira plus vite", c'est faux.
                                                    Le nombre de thread qui peut tourner de manière simultané ("réellement") dépend du nombre de cœur de ton processeur (que tu peux multiplier par ton nombre de processeur, mais ça c'est une autre histoire).
                                                    Donc, si ton PC n'as qu'un cœur (physique, pas logique), alors la version multithreading prendra toujours plus de temps que la version séquentielle.
                                                    2, 4 ou 8 thread, c'est assez commun, mais ca dépend du matos sur lequel tourne le programme.

                                                    Bref, as-tu regardé / compris le code que j'ai posté avant ?

                                                    -
                                                    Edité par Anonyme 24 novembre 2017 à 15:02:19

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      24 novembre 2017 à 15:27:06

                                                      SofEvans2 a écrit:

                                                      Donc, si ton PC n'as qu'un cœur (physique, pas logique), alors la version multithreading prendra toujours plus de temps que la version séquentielle.
                                                      2, 4 ou 8 thread, c'est assez commun, mais ca dépend du matos sur lequel tourne le programme.

                                                      Sur un processeur monocore hyperthreadé, on devrait théoriquement gagner des perfs avec un deuxième thread, non?

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                      Anonyme
                                                        24 novembre 2017 à 15:50:41

                                                        J'aimerais éviter de dire des bétises, mais je me lance :

                                                        Je croyais que c'était le nombre de cœur qu'un processeur possédait qui determinait à quel point le multi-threading pouvait être correcte (enfin, entre autre).
                                                        Je n'ai pas connaissance de ce qu'est réellement un "processeur monocore hyperthreadé", mais ca ressemble a des coeur logique non ? (1 processeur monocore qui simule plusieurs coeur).

                                                        Donc oui, théoriquement, on devrait gagner en perf.
                                                        Maintenant, l'usage du multi-threading à un coût (création, synchronisation, nettoyage, etc etc) qui fait que multi-threadé une action qui prends moins de 1s n'as pas d'impact si visible.

                                                        J'ai exécuté le programme pour voir,  et ce qui est rigolo, c'est que les deux courbes ont exactement la même tête, comme si

                                                        f(temp sequentielle) = x
                                                        f(temp parallete) = x + 0.000002

                                                        Je sais pas si je suis clair ?
                                                        Du coup, ca me donne réellement l'impression que le "+ 0.000002" c'est le coût de création et de fonctionnement des threads.
                                                        Mais impossible à confirmer comme ca, donc ca reste du domaine de l'impression.

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Anonyme
                                                          24 novembre 2017 à 19:36:13

                                                          J'ai exécuté le code, je vais regarder si je comprends bien tout ce que tu as noté, encore une fois merci.
                                                          Par contre j'ai ce résultat, est ce que c'est normal ? Parce que on a du mal a lire les courbes et les différencier du coup 
                                                          https://puu.sh/ysLtN/ba06643feb.png
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Anonyme
                                                            24 novembre 2017 à 21:29:16

                                                            Tu peux scroller dans la fenêtre, deplacer avec les fléches.

                                                            Des données anormale, ca peut arriver.
                                                            La question (pour mettre de coté ces données), c'est est-ce qu'une seule des courbes à un pic (en ce cas, anormal), est-ce que les pic interviennent toujours au même moment (à investiguer si c'est le cas), et est-ce que ce ne serait pas lié à ton pc ?

                                                            Quand j'ai fais mon test, a un moment, le PC a saturer (je sais pas pourquoi, un autre truc qui tournait sans doute), et mes deux courbes ont bondis.
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              24 novembre 2017 à 23:05:14

                                                              C'est sur les deux courbes et à des endroits différents à chaque exécution donc ça doit venir de mon PC. J'ai regardé le code, ça me paraît clair, peut être que j'aurai une question auquel cas je viendrais la poster ici.

                                                              Je devais faire une exécution avec du séquentiel puis du parallèle et enfin avec des sémaphores donc je vais m'intéresser aux sémaphores et regarder comment coder ça

                                                              Merci encore à vous de m'avoir aider 

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Erreur de segmentation - Threads

                                                              × 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