我是新手,也是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 );
}
}
代码从伽马随机分布中抽取M次迭代。事实证明,使用openmp(选项1)的并行方法大约需要1分钟,而顺序方法(选项2)只需要20秒。使用openmp运行时,我可以看到CPU使用率为800%(我使用的服务器有8个CPU)。系统是使用GCC 4.1.3的linux。我正在使用的编译命令是gcc -fopenmp -lgsl -lgslcblas -lm(我正在使用GSL)
我做错了吗?请帮我!谢谢!
P.S。正如一些用户所指出的,它可能是由rng引起的。但即使我更换
tmp=gsl_ran_gamma_mt(rng, 4, 1./3 );
说
tmp=1000*10000;
问题仍然存在......
答案 0 :(得分:12)
gsl_ran_gamma_mt
可能锁定rng
以防止并发问题(如果没有,您的并行代码可能包含竞争条件,从而产生错误的结果)。然后解决方案是为每个线程分别创建一个rng
实例,从而避免锁定。
答案 1 :(得分:5)
您的rng
变量是共享的,因此线程花费所有时间等待能够使用随机数生成器。为每个线程提供一个单独的RNG实例。这可能意味着使RNG初始化代码也并行运行。
答案 2 :(得分:1)
再次感谢大家的帮助。我刚刚发现,如果我摆脱
schedule(dynamic)
在代码中,问题消失了。但那为什么呢?