2015-04-02 34 views
1

我一直在嘗試爲pthreads製作一個dot產品程序,我一直有一些困難。我嘗試運行程序時遇到分段錯誤。我使用c來編碼它。使用pthreads爲dotproduct時的分段錯誤

我有程序,此代碼最初工作:

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); 
    } 

然後,我改變了內存分配,因爲我沒有想的和通過增加線程數增加。

這是改變的代碼:

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); 
    } 

這是我的代碼的全部:

#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); 

} 

回答

1

在初始代碼,dot.sizeSIZE是相同的東西,並在矢量大小是SIZE * THREAD_COUNT。所以,如果你有4個線程,每個線程做5點乘,則矢量大小爲20

在新的代碼,SIZE現在是矢量的大小,以及你試圖分裂THREAD_COUNT線程之間的工作。因此dot.size需要是SIZE/THREAD_COUNT。所以如果SIZE是20並且THREAD_COUNT是4,那麼dot.size需要是20/4 = 5.

+0

謝謝你,它現在工作完美。你先生,太棒了。 – 2015-04-02 02:32:57