我正在写一个c脚本来平行pi近似与OpenMp。我认为我的代码工作正常,有一个令人信服的输出。我现在用4个线程运行它。我不确定的是,如果这段代码容易受到竞争状况的影响?如果是这样,我如何协调此代码中的线程操作?蒙特卡罗pi逼近的并行化
的代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <omp.h>
double sample_interval(double a, double b) {
double x = ((double) rand())/((double) RAND_MAX);
return (b-a)*x + a;
}
int main (int argc, char **argv) {
int N = atoi(argv[1]); // convert command-line input to N = number of points
int i;
int NumThreads = 4;
const double pi = 3.141592653589793;
double x, y, z;
double counter = 0;
#pragma omp parallel firstprivate(x, y, z, i) reduction(+:counter) num_threads(NumThreads)
{
srand(time(NULL));
for (int i=0; i < N; ++i)
{
x = sample_interval(-1.,1.);
y = sample_interval(-1.,1.);
z = ((x*x)+(y*y));
if (z<= 1)
{
counter++;
}
}
}
double approx_pi = 4.0 * counter/ (double)N;
printf("%i %1.6e %1.6e\n ", N, 4.0 * counter/ (double)N, fabs(4.0 * counter/ (double)N - pi)/pi);
return 0;
}
此外,我在想,如果随机数种子应内部或外部并行申报。我的输出如下所示:
10 3.600000e+00 1.459156e-01
100 3.160000e+00 5.859240e-03
1000 3.108000e+00 1.069287e-02
10000 3.142400e+00 2.569863e-04
100000 3.144120e+00 8.044793e-04
1000000 3.142628e+00 3.295610e-04
10000000 3.141379e+00 6.794439e-05
100000000 3.141467e+00 3.994585e-05
1000000000 3.141686e+00 2.971945e-05
现在看起来不错。你对种族条件和种子安置的建议是最受欢迎的。
什么的'文档'rand()''和''srand()''说?如果他们说,数字发生器的状态保存在线程本地存储中,至少这不会是一个问题。但他们是这么说的吗?这里:http://www.cplusplus.com/reference/cstdlib/rand/他们说那些比赛可能会发生。 – BitTickler