我有以下代码用多个线程填充数组:
#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
,但似乎需要比正常填充更长的时间。任何建议为什么会这样?
答案 0 :(得分:1)
我怀疑主要的瓶颈是对rand()
的调用。 rand()
不需要是线程安全的。因此,当多个线程可以同时调用rand()
时,它不能安全地用在多线程程序中。但是Glibc实现使用内部锁来防止这种用途。这有效地将所有线程中的rand()
的调用序列化,从而严重影响程序的多线程性质。相反,使用不需要维护任何内部状态的rand_r()
(因为调用者都这样做)并且至少可以解决问题的这个方面。
通常,如果线程没有做足够的工作,那么线程创建/同步开销可能超过使用线程在多核系统上可用的并发性。