OpenMP和C并行for循环:为什么我的代码在使用OpenMP时会变慢?

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

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

代码从M个迭代的伽马随机分布中提取。 事实certificate,使用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; 

问题仍然存在……

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

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

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

 schedule(dynamic) 

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