2015-04-02 3 views
1

J'ai essayé de créer un programme de produit scalaire pour pthreads et j'ai rencontré quelques difficultés. Im obtenir une erreur de segmentation lorsque j'essaie d'exécuter le programme. J'utilise c pour le coder.Erreur de segmentation lors de l'utilisation de pthreads pour dotproduct

J'ai eu le programme de travail d'abord avec ce code:

a = (double*) malloc (THREAD_COUNT* SIZE * sizeof(double)); 
b = (double*) malloc (THREAD_COUNT* SIZE * sizeof(double)); 

for (i=0; i<SIZE*THREAD_COUNT; i++) { 
    a[i]=1; 
    b[i]=a[i]; 
    } 

dot.size = SIZE; 
dot.a = a; 
dot.b = b; 
dot.sum=0; 

pthread_mutex_init(&mutexsum, NULL); 

/* Create threads to perform the dotproduct */ 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 


gettimeofday (&time_start, NULL); 

for(i=0;i<THREAD_COUNT;i++) 
    { 

    pthread_create(&callThd[i], &attr, dotprod, (void *)i); 
    } 

pthread_attr_destroy(&attr); 

for(i=0;i<THREAD_COUNT;i++) { 
    pthread_join(callThd[i], &status); 
    } 

Puis j'ai changé l'allocation de mémoire parce que je ne voulais pas la somme d'augmenter en augmentant le nombre de threads.

c'est le code modifié:

a = (double*) malloc (SIZE * sizeof(double)); 
b = (double*) malloc (SIZE * sizeof(double)); 

for (i=0; i<SIZE; i++) { 
    a[i]=1; 
    b[i]=a[i]; 
    } 

dot.size = SIZE; 
dot.a = a; 
dot.b = b; 
dot.sum=0; 

pthread_mutex_init(&mutexsum, NULL); 

/* Create threads to perform the dotproduct */ 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 


gettimeofday (&time_start, NULL); 

for(i=0;i<THREAD_COUNT;i++) 
    { 

    pthread_create(&callThd[i], &attr, dotprod, (void *)i); 
    } 

pthread_attr_destroy(&attr); 

for(i=0;i<THREAD_COUNT;i++) { 
    pthread_join(callThd[i], &status); 
    } 

Ceci est l'ensemble de mon code:

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/time.h> //gettimeofday() 
typedef struct 
{ 
    double  *a; 
    double  *b; 
    double  sum; 
    int  size; 
} DOTPROD; 

/* Define globally accessible variables and a mutex */ 

typedef struct 
{ 

int secs; 
int microsecs; 


}TIME; 

//TIME * time_diff(struct timeval *, struct timeval *); 


#define THREAD_COUNT 20 
#define SIZE 100000 
    DOTPROD dot; 
    pthread_t callThd[THREAD_COUNT]; 
    pthread_mutex_t mutexsum; 






void *dotprod(void *arg) 
{ 

/* Define and use local variables for convenience */ 

    int i, start, end, reg_size ; 
    long offset; 
    double partsum, *x, *y; 
    offset = (long)arg; 

    reg_size = dot.size; 
    start = offset*reg_size; 
    end = start + reg_size; 
    x = dot.a; 
    y= dot.b;  /*           
* Perform the dot product and assign result 
* to the appropriate variable in the structure. 
* */ 
    partsum = 0; 
    for (i=start; i<end ; i++) 
    { 
     partsum += (x[i] * y[i]); 
    } 

/* 
* Lock a mutex prior to updating the value in the shared 
* structure, and unlock it upon updating. 
* */ 
    pthread_mutex_lock (&mutexsum); 
    dot.sum += partsum; 
    pthread_mutex_unlock (&mutexsum); 

    pthread_exit((void*) 0); 
} 



int main (int argc, char *argv[]) 
{ 
long i; 
double *a, *b; 
void *status; 
struct timeval time_start, time_end; 

TIME*diff; 
pthread_attr_t attr; 
/* Assign storage and initialize values */ 

a = (double*) malloc (SIZE * sizeof(double)); 
b = (double*) malloc (SIZE * sizeof(double)); 

for (i=0; i<SIZE; i++) { 
    a[i]=1; 
    b[i]=a[i]; 
    } 

dot.size = SIZE; 
dot.a = a; 
dot.b = b; 
dot.sum=0; 

pthread_mutex_init(&mutexsum, NULL); 

/* Create threads to perform the dotproduct */ 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
                55,16   58% 
* Perform the dot product and assign result 
* to the appropriate variable in the structure. 
* */ 
    partsum = 0; 
    for (i=start; i<end ; i++) 
    { 
     partsum += (x[i] * y[i]); 
    } 

/* 
* Lock a mutex prior to updating the value in the shared 
* structure, and unlock it upon updating. 
* */ 
    pthread_mutex_lock (&mutexsum); 
    dot.sum += partsum; 
    pthread_mutex_unlock (&mutexsum); 

    pthread_exit((void*) 0); 
} 



int main (int argc, char *argv[]) 
{ 
long i; 
double *a, *b; 
void *status; 
struct timeval time_start, time_end; 

TIME*diff; 
pthread_attr_t attr; 
/* Assign storage and initialize values */ 

a = (double*) malloc (SIZE * sizeof(double)); 
b = (double*) malloc (SIZE * sizeof(double)); 

for (i=0; i<SIZE; i++) { 
    a[i]=1; 
    b[i]=a[i]; 
    } 

dot.size = SIZE; 
dot.a = a; 
dot.b = b; 
dot.sum=0; 

pthread_mutex_init(&mutexsum, NULL); 

/* Create threads to perform the dotproduct */ 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
                55,16   58% 
* Perform the dot product and assign result 
* to the appropriate variable in the structure. 
* */ 
    partsum = 0; 
    for (i=start; i<end ; i++) 
    { 
     partsum += (x[i] * y[i]); 
    } 

/* 
* Lock a mutex prior to updating the value in the shared 
* structure, and unlock it upon updating. 
* */ 
    pthread_mutex_lock (&mutexsum); 
    dot.sum += partsum; 
    pthread_mutex_unlock (&mutexsum); 

    pthread_exit((void*) 0); 
} 



int main (int argc, char *argv[]) 
{ 
long i; 
double *a, *b; 
void *status; 
struct timeval time_start, time_end; 

TIME*diff; 
pthread_attr_t attr; 
/* Assign storage and initialize values */ 

a = (double*) malloc (SIZE * sizeof(double)); 
b = (double*) malloc (SIZE * sizeof(double)); 

for (i=0; i<SIZE; i++) { 
    a[i]=1; 
    b[i]=a[i]; 
    } 

dot.size = SIZE; 
dot.a = a; 
dot.b = b; 
dot.sum=0; 

pthread_mutex_init(&mutexsum, NULL); 

/* Create threads to perform the dotproduct */ 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
                55,16   58% 
* Perform the dot product and assign result 
* to the appropriate variable in the structure. 
* */ 
    partsum = 0; 
    for (i=start; i<end ; i++) 
    { 
     partsum += (x[i] * y[i]); 
    } 

/* 
* Lock a mutex prior to updating the value in the shared 
* structure, and unlock it upon updating. 
* */ 
    pthread_mutex_lock (&mutexsum); 
    dot.sum += partsum; 
    pthread_mutex_unlock (&mutexsum); 

    pthread_exit((void*) 0); 
} 



int main (int argc, char *argv[]) 
{ 
long i; 
double *a, *b; 
void *status; 
struct timeval time_start, time_end; 

TIME*diff; 
pthread_attr_t attr; 
/* Assign storage and initialize values */ 

a = (double*) malloc (SIZE * sizeof(double)); 
b = (double*) malloc (SIZE * sizeof(double)); 

for (i=0; i<SIZE; i++) { 
    a[i]=1; 
    b[i]=a[i]; 
    } 

dot.size = SIZE; 
dot.a = a; 
dot.b = b; 
dot.sum=0; 

pthread_mutex_init(&mutexsum, NULL); 

/* Create threads to perform the dotproduct */ 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
                * Perform the dot product and assign result 
* to the appropriate variable in the structure. 
* */ 
    partsum = 0; 
    for (i=start; i<end ; i++) 
    { 
     partsum += (x[i] * y[i]); 
    } 

/* 
* Lock a mutex prior to updating the value in the shared 
* structure, and unlock it upon updating. 
* */ 
    pthread_mutex_lock (&mutexsum); 
    dot.sum += partsum; 
    pthread_mutex_unlock (&mutexsum); 

    pthread_exit((void*) 0); 
} 



int main (int argc, char *argv[]) 
{ 
long i; 
double *a, *b; 
void *status; 
struct timeval time_start, time_end; 

TIME*diff; 
pthread_attr_t attr; 
/* Assign storage and initialize values */ 

a = (double*) malloc (SIZE * sizeof(double)); 
b = (double*) malloc (SIZE * sizeof(double)); 

for (i=0; i<SIZE; i++) { 
    a[i]=1; 
    b[i]=a[i]; 
    } 

dot.size = SIZE; 
dot.a = a; 
dot.b = b; 
dot.sum=0; 

pthread_mutex_init(&mutexsum, NULL); 

/* Create threads to perform the dotproduct */ 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 

gettimeofday (&time_start, NULL); 

for(i=0;i<THREAD_COUNT;i++) 
    { 

    pthread_create(&callThd[i], &attr, dotprod, (void *)i); 
    } 

pthread_attr_destroy(&attr); 

for(i=0;i<THREAD_COUNT;i++) { 
    pthread_join(callThd[i], &status); 
    } 
/* After joining, print out the results and cleanup */ 



gettimeofday (&time_end, NULL); 


long long elasped = (time_end.tv_sec - time_start.tv_sec)*1000000LL + time_end.tv_usec - time_start.tv_usec; 

printf ("time diff in microseconds = %6d \n",elasped); 

printf ("Sum = %f \n", dot.sum); 
//diff = time_diff(&time_start, &time_end); 

//printf("Time = %d. \%5d.%6d secs. \n", diff->secs, diff -> microsecs); 
free (a); 
free (b); 
pthread_mutex_destroy(&mutexsum); 
pthread_exit(NULL); 

} 

Répondre

1

Dans le code initial, dot.size et SIZE étaient la même chose, et la taille du vecteur était SIZE * THREAD_COUNT. Donc, si vous aviez 4 threads et que chaque thread faisait 5 multiplications, la taille du vecteur était 20.

Dans le nouveau code, SIZE est maintenant la taille du vecteur, et vous essayez de diviser le travail entre les threads THREAD_COUNT. Par conséquent dot.size doit être SIZE/THREAD_COUNT. Donc, si SIZE est 20 et THREAD_COUNT est 4, alors dot.size doit être 20/4 = 5.

+0

MERCI, cela fonctionne parfaitement maintenant. Vous êtes génial, monsieur. –