以下程序与here中描述的程序基本相同。当我运行和编译使用两个线程(来确定nthreads == 2),我得到以下运行时间程序:多线程random_r比单线程版本更慢
real 0m14.120s
user 0m25.570s
sys 0m0.050s
当它运行只有一个线程(来确定nthreads == 1),我得到的运行时间即使只使用一个核心也会明显更好。
real 0m4.705s
user 0m4.660s
sys 0m0.010s
我的系统是双核心的,我知道random_r是线程安全的,我非常肯定它是非阻塞的。当同样的程序在没有random_r的情况下运行并且使用余弦和正弦的计算作为替换时,双线程版本的运行时间大约是预期的1/2。
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define NTHREADS 2
#define PRNG_BUFSZ 8
#define ITERATIONS 1000000000
void* thread_run(void* arg) {
int r1, i, totalIterations = ITERATIONS/NTHREADS;
for (i = 0; i < totalIterations; i++){
random_r((struct random_data*)arg, &r1);
}
printf("%i\n", r1);
}
int main(int argc, char** argv) {
struct random_data* rand_states = (struct random_data*)calloc(NTHREADS, sizeof(struct random_data));
char* rand_statebufs = (char*)calloc(NTHREADS, PRNG_BUFSZ);
pthread_t* thread_ids;
int t = 0;
thread_ids = (pthread_t*)calloc(NTHREADS, sizeof(pthread_t));
/* create threads */
for (t = 0; t < NTHREADS; t++) {
initstate_r(random(), &rand_statebufs[t], PRNG_BUFSZ, &rand_states[t]);
pthread_create(&thread_ids[t], NULL, &thread_run, &rand_states[t]);
}
for (t = 0; t < NTHREADS; t++) {
pthread_join(thread_ids[t], NULL);
}
free(thread_ids);
free(rand_states);
free(rand_statebufs);
}
我很困惑,为什么产生随机数当两个线程版本的性能比单线程版本差多少,考虑random_r是指在多线程应用中使用。
呃。这可以咬住几乎任何小的,密集的结构,多线程将尝试写入部分,对吗? – 2010-06-08 20:03:28
非常感谢您的帮助,我绝对不会想到这一点。 Ps。我将rand_states和rand_statebufs移入线程,并从那里初始化随机数生成器。这也很好地解决了缓存问题。 – Nixuz 2010-06-08 20:06:38
@尼古拉斯:是的。记住不要过分吝啬。请注意,将线程本地分配放在一起也可以提供帮助。由于可以避免高速缓存争用和锁定,因此线程本地机器人可以是一个巨大的胜利。 – 2010-06-08 20:13:34