Wal*_*oni 2 c multithreading synchronization openmp
我想制作一些示例代码以测试Open MP API.我已经制作了一个三级For循环,其中包含了一个calcul.
问题是我的结果是错的.
这是我的代码:
long value = 0;
#pragma omp parallel
{
#pragma omp for
for (int i=0;i<=9999;i++)
{
value += (M_PI * i * i -12,33 * M_PI)- M_PI;
for (int j=0;j<=888;j++)
{
value += (M_PI * j * i -12,33 * M_PI)- M_PI;
for (int k=0;k<=777;k++)
{
value += (M_PI * k * j -12,33 * M_PI)- M_PI;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题 :
如果没有Open MP,value变量的值为:191773766
Whit Open MP,value变量的值为: 1092397966
我认为这是一个同步问题,但如何解决这个问题呢?我已经阅读了很多关于Open MP的内容,但我找不到如何解决它.
非常感谢,
最好的祝福,
你错过了这个reduction(+:value)条款.
#pragma omp parallel reduction(+:value) // add reduction here
{
#pragma omp for
Run Code Online (Sandbox Code Playgroud)
您需要它的原因是因为您value在所有线程中共享变量.所以他们异步更新它导致竞争条件.(您还可以从缓存一致性中获得性能提升.)
该reduction(+:value)子句告诉编译value为每个线程创建一个单独的实例,然后在最后总结它们.
编辑:OP请求的完整代码.
int main() {
double start = omp_get_wtime();
long M_PI = 12;
long value = 0;
#pragma omp parallel reduction(+:value)
{
#pragma omp for
for (int i=0;i<=9999;i++)
{
value += (M_PI * i * i -12,33 * M_PI)- M_PI;
for (int j=0;j<=888;j++)
{
value += (M_PI * j * i -12,33 * M_PI)- M_PI;
for (int k=0;k<=777;k++)
{
value += (M_PI * k * j -12,33 * M_PI)- M_PI;
}
}
}
}
double end = omp_get_wtime();
printf("\n\nseconds = %f\n",end - start);
cout << value << endl;
system("pause");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:(没有OpenMP)
seconds = 0.007816
738123776
Run Code Online (Sandbox Code Playgroud)
输出:(使用OpenMP - 8个线程)
seconds = 0.012784
738123776
Run Code Online (Sandbox Code Playgroud)
如果你想要的任何加速,你需要做的工作很多大.