在 C 中用多个线程填充数组

Fill array with multiple threads in C

我有以下用多个线程填充数组的代码:

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

我给每个线程 1/8 的数组来填充 LINES_PER_THREAD,但似乎比正常填充它需要更长的时间。任何建议为什么会这样?

我怀疑主要瓶颈是对 rand() 的调用。 rand() 不需要线程安全。因此,当多个线程可以同时调用 rand() 时,它不能安全地用于多线程程序。但是 Glibc 实现使用内部锁来防止此类使用。这有效地序列化了所有线程中对 rand() 的调用,从而严重影响了程序的多线程特性。而是使用 rand_r(),它不需要维护任何内部状态(因为调用者需要维护)并且至少可以解决您问题的这方面。

一般来说,如果线程没有做足够的工作,那么线程 creation/synchronization 开销可能会超过使用线程的多核系统上可用的并发性。