Ошибка сегментации при работе с массивом большого размера - PullRequest
0 голосов
/ 10 декабря 2018

Я пытался использовать 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;
}

1 Ответ

0 голосов
/ 10 декабря 2018
for(i;i<i+CHUNK;i++)

Поскольку i всегда будет меньше i + CHUNK (если не переполняется), этот цикл будет выходить за границы массива.

...