Я пытался использовать Pthreads в программе для подсчета 3-х единиц в массиве int элемента 3000000, и когда он работает последовательно без использования pthreads, он отлично работает.
Использование pthreads приводит к сегментациивина, и я не могу понять, почему.выполнение останавливается, когда каждый поток достигает примерно 300000 итераций в случае 4 потоков в 8 ГБ ОЗУ и 256 КБ L2-кэша.
Вот мой код
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#define LENGTH 3000000
#define NUM_THREADS 4
int countarr[128];
int* array;
struct Op_data{
int start_index;
int count_index;
int CHUNK;
int ID;
};
void* count3s(void* data) // you need to parallelize this
{
struct Op_data *info;
info = (struct Op_data *) data;
int count_i = info -> count_index;
int i = info->start_index;
int CHUNK = info -> CHUNK;
printf("Thread data:\nCOUNT_INDEX:\t\t%d\nSTART_INDEX:\t\t%d\nCHUNK_SIZE:\t\t%d\n",count_i,i,CHUNK);
int c = 0;
struct timeval t1, t2;
gettimeofday(&t1, NULL);
for(i;i<i+CHUNK;i++)
{
if(array[i]==3)
{
c++;
}
}
countarr[count_i] = c;
gettimeofday(&t2, NULL);
double t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec ) / 1000000.0;
printf("execution time = %f seconds\n",t);
}
int main(int argc, char * argv[])
{
int i = 0;
int ok = 0;
int count=0;
array = malloc(LENGTH * sizeof(int));
// initialize the array randomly. Make sure the number of 3's doesn't exceed 500000
srand(12);
for(i= 0;i<LENGTH;i++)
{
array[i]=rand()%10;
if(array[i]==3)
{
ok++; // keep track of how many 3's are there, we will use this later to confirm the correctness of the code
if(ok>500000)
{
ok=500000;
array[i]=12;
}
}
}
pthread_t threads[NUM_THREADS];
struct Op_data* t_data[NUM_THREADS];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
int rc;
int CHUNK = LENGTH/NUM_THREADS;
for(int t=0;t<NUM_THREADS;t++)
{
t_data[t] = (struct Op_data*) malloc(sizeof(struct Op_data));
t_data[t] -> start_index = t*CHUNK;
t_data[t] -> count_index = t*(128/NUM_THREADS);
t_data[t] -> CHUNK = CHUNK;
t_data[t] -> ID = t;
rc = pthread_create(&threads[t], &attr, count3s, (void *)t_data[t]);
if (rc) {
printf("Error:unable to create thread,%d\n",rc);
exit(-1);
}
printf("Thread (%d) has been created.\n",t);
}
for( int g = 0; g < NUM_THREADS; g++ ) {
rc = pthread_join(threads[g], NULL);
if (rc) {
printf("Error:unable to join,%d\n",rc);
exit(-1);
}
}
pthread_attr_destroy(&attr);
for(int x=0;x<NUM_THREADS;x++)
{
count += countarr[x*(128/NUM_THREADS)];
}
if( ok == count ) // check if the result is correct
{
printf("Correct Result!\n");
printf("Number of 3`s: %d\n_________________________________\n",count);
}
else
{
printf("Wrong Result! Your count:%d\n",count);
printf("The correct number of 3`s is: %d\n",ok);
}
pthread_exit(NULL);
return 0;
}