9

我是这里的新手,也是 C 语言的初级程序员。我在使用 openmp 加速 for 循环时遇到了一些问题。下面是一个简单的例子:

#include <stdlib.h>
#include <stdio.h>
#include <gsl/gsl_rng.h>
#include <omp.h>

gsl_rng *rng;

main()
{
int i, M=100000000;
double tmp;

/* initialize RNG */
gsl_rng_env_setup();
rng = gsl_rng_alloc (gsl_rng_taus);
gsl_rng_set (rng,(unsigned long int)791526599);

// option 1: parallel        
  #pragma omp parallel for default(shared) private( i, tmp ) schedule(dynamic)
  for(i=0;i<=M-1;i++){
     tmp=gsl_ran_gamma_mt(rng, 4, 1./3 );
  }


// option 2: sequential       
  for(i=0;i<=M-1;i++){
     tmp=gsl_ran_gamma_mt(rng, 4, 1./3 );
  }
}

该代码从 Gamma 随机分布中提取 M 次迭代。事实证明,使用 openmp 的并行方法(选项 1)大约需要 1 分钟,而顺序方法(选项 2)只需 20 秒。使用 openmp 运行时,我可以看到 CPU 使用率为 800%(我使用的服务器有 8 个 CPU)。系统是带有GCC 4.1.3的linux。我正在使用的编译命令是 gcc -fopenmp -lgsl -lgslcblas -lm (我正在使用 GSL )

难道我做错了什么?请帮我!谢谢!

PS 正如一些用户所指出的,它可能是由 rng 引起的。但即使我更换

tmp=gsl_ran_gamma_mt(rng, 4, 1./3 );

tmp=1000*10000;

问题仍然存在...

4

3 回答 3

12

gsl_ran_gamma_mt可能会锁定rng以防止并发问题(如果没有,您的并行代码可能包含竞争条件,因此会产生错误的结果)。然后解决方案是rng为每个线程设置一个单独的实例,从而避免锁定。

于 2012-08-23T15:58:54.697 回答
5

您的rng变量是共享的,因此线程正在花费所有时间等待能够使用随机数生成器。给每个线程一个单独的 RNG 实例。这可能意味着使 RNG 初始化代码也并行运行。

于 2012-08-23T15:58:57.407 回答
1

再次感谢大家的帮助。我刚刚发现如果我摆脱

schedule(dynamic)

在代码中,问题消失了。但这是为什么呢?

于 2012-08-23T18:23:25.413 回答