与OpenMP同步,For指令

时间:2012-06-18 20:52:13

标签: c multithreading synchronization openmp

我想制作一些示例代码以测试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 Whit Open MP,value变量的值为:1092397966

我认为这是同步问题,但如何解决这个问题呢? 我已经阅读了很多关于Open MP的内容,但我找不到如何解决它。

非常感谢,

致以最诚挚的问候,

1 个答案:

答案 0 :(得分:7)

你错过了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

如果您想要任何加速,您需要使任务更多更大。