我想制作一些示例代码来测试 Open MP API。 我在其中做了一个带有计算的三级 For 循环。
问题是我的结果是错误的。
这是我的代码:
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;
}
}
}
}
我的问题:
没有 Open MP,value
变量的值为:191773766
在 Open MP 中,value
变量的值为:1092397966
我认为这是一个同步问题,但如何解决呢? 我已经阅读了很多关于 Open MP 的内容,但我没有找到解决方法。
非常感谢,
最好的问候,
最佳答案
您缺少 reduction(+:value)
子句。
#pragma omp parallel reduction(+:value) // add reduction here
{
#pragma omp for
您之所以需要它,是因为您要在所有线程之间共享 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;
}
输出:(没有 OpenMP)
seconds = 0.007816
738123776
输出:(使用 OpenMP - 8 个线程)
seconds = 0.012784
738123776
如果您想要任何加速,您需要使任务大得多。
关于c - 与 OpenMP 同步,For 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11090831/