pi计算的OpenMP并行化要么是缓慢的,要么是错误的

我无法并行化我的monte carlo方法来计算pi。 这是并行化的for循环:

#pragma omp parallel for private(i,x,y) schedule(static) reduction(+:count) for (i = 0; i < points; i++) { x = rand()/(RAND_MAX+1.0)*2 - 1.0; y = rand()/(RAND_MAX+1.0)*2 - 1.0; // Check if point lies in circle if(x*x + y*y < 1.0) { count++; } } 

问题是,如果我使用schedule(static) ,它会低估pi,如果我使用schedule(static) ,它比串行实现慢。 我究竟做错了什么? 我已经尝试了其他方法来解决它(像这样: 使用OpenMP来计算PI的值 ),但它仍然比串行实现慢得多。

提前致谢

假设您正在使用C库rand函数,该函数不可重入或线程安全。 POSIX提供了一个rand_r函数,但是(引用glibc文档):

POSIX.1扩展了C标准函数,以支持multithreading程序中可重现的随机数。 但是,扩展设计糟糕,不适合认真工作。

特别是,种子必须是unsigned int,它没有足够的位用于良好的PRNG。 他们建议使用SVID随机数函数,其中nrand48_r可能是您正在寻找的。

或者,您可以使用其他库。

在并行执行此类操作时,您必须考虑的一件事是,由于执行计算的方式不同,可能会出现不同的舍入错误。

例:

((A+B) + (C+D))其中(A+B)(C+D)并行计算可能与串行方法(((A+B) + C) + D)