Fill array with multiple threads in C

2.6k views Asked by At

I have the following code of filling an array with multiple threads:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define MAX_ITEMS 67108864
#define LINES_PER_THREAD 8388608
#define THREADS 8
static int *array;

static pthread_t pids[THREADS];
static int args[THREADS];


static void init_array_line(int *line) {
    int i, max;
    i = *line;
    max = i + LINES_PER_THREAD;
    for (i; i < max; i++)
        array[i] = rand() % 10000 + 1;
}

static void init_array() {
     int i;
    for ( i = 0; i < THREADS; i++) {
        args[i]=i* LINES_PER_THREAD;
        pthread_create(pids + i, NULL, &init_array_line, args + i);;
    }
}

static wait_all() {
    for (int i = 0; i < THREADS; i++) {
        pthread_join(pids[i], NULL);
    }
}

int
main(int argc, char **argv)
{
    array = (int *)malloc(MAX_ITEMS * sizeof(int));
    init_array();
    wait_all();
}

I am giving each thread 1/8 of the array to fill LINES_PER_THREAD, but it seems that it takes longer than filling it normally. Any suggestions why might this be?

1

There are 1 answers

5
P.P On BEST ANSWER

I suspect the main bottleneck would the calls to rand(). rand() isn't required to be thread-safe. So, it can't be safely used in a multi-threaded program when multiple threads could call rand() concurrently. But the Glibc implementation uses an internal lock to protect against such uses. This effectively serializes the call to rand() in all threads and thus severely affecting the multi-threaded nature of your program. Instead use rand_r() which doesn't need to maintain any internal state (because the caller(s) do) and can at least solve this aspect of your problem.

In general, if the threads don't do sufficient work then the thread creation/synchronization overhead can outdo the concurrency that could be available on multi-core systems using threads.