当我尝试以下代码时
double start = omp_get_wtime();
long i;
#pragma omp parallel for
for (i = 0; i <= 1000000000; i++) {
double x = rand();
}
double end = omp_get_wtime();
printf("%f\n", end - start);
执行时间约为168秒,而顺序版本仅花费20秒。
我仍然是并行编程的新手。我怎么能得到一个比顺序版更快的并行版本?
答案 0 :(得分:13)
随机数生成器rand(3)
使用全局状态变量(隐藏在(g)libc实现中)。从多个线程访问它们会导致缓存问题,也不是线程安全的。您应该使用rand_r(3)
调用seed
参数私有线程:
long i;
unsigned seed;
#pragma omp parallel private(seed)
{
// Initialise the random number generator with different seed in each thread
// The following constants are chosen arbitrarily... use something more sensible
seed = 25234 + 17*omp_get_thread_num();
#pragma omp for
for (i = 0; i <= 1000000000; i++) {
double x = rand_r(&seed);
}
}
请注意,当并行执行时,这将产生不同的随机数流,而不是串行执行时。我还建议将erand48(3)
作为更好的(伪)随机数源。