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

时间:2012-01-24 17:16:12

标签: c++ c parallel-processing 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(dynamic),它比串行实现慢。我究竟做错了什么?我已尝试过其他方法来修复它(如:Using OpenMP to calculate the value of PI)但它仍然比串行实现慢得多。

提前致谢

2 个答案:

答案 0 :(得分:6)

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

  

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

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

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

答案 1 :(得分:1)

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

示例:

并行计算((A+B) + (C+D))(A+B)

(C+D)可能与序列方法(((A+B) + C) + D)不同。