Openmp - for for's for's

时间:2015-09-15 16:13:23

标签: c++ openmp

我试图并行化" for"用openmp。 但是,并行代码与非并行的结果是不同的。我认为它与循环之外的 sum 变量的定义有关,但我不知道如何解决问题。

我想要的是并行化第一个" for"循环。

编辑:1

这是我能找到的最简单的例子。

//g++ -o test2 test2.cpp -fopenmp
//
//

#include <cmath>
#include <iostream>

using namespace std;

double f(double i, double j)
{
return i + j;
}

int main()
{
const int size = 256;
double sum = 0;

//will use openmp
#pragma omp parallel for
for(int i = 0; i < size; i = i + 1)
{
    for(int j = 0; j < size; j=j+1)
    {
        if(i != j)
        {
            sum = sum + f(i,j);
        }
    }

}

cout << "sum = " << sum << endl;


//not using openmp
sum = 0;
for(int i = 0; i < size; i = i + 1)
{
    for(int j = 0; j < size; j=j+1)
    {
        if(i != j)
        {
            sum = sum + f(i,j);
        }
    }

}

cout << "sum = " << sum << endl;  

}

2 个答案:

答案 0 :(得分:0)

您的问题是多个线程正在执行sum的访问权限。即当第一个线程达到

sum=sum+f(i,j);

它抓取sum,进行计算,将结果写入sum。当同时另一个线程到达该行时,它会抓取旧值sum并转储其结果,覆盖第一个线程结果。

解决方案是设置

double increment=f(i,j);
#pragma omp critical
sum+=increment;

另请注意,您的代码结果不可预测,并且在您多次运行时会发生更改。

答案 1 :(得分:0)

感谢您的回答,它终于有效了。

以下代码是Christoph Solution的工作代码。

//g++ -o test2 test2.cpp -fopenmp

#include <cmath>
#include <iostream>

using namespace std;

double f(double i, double j)
{
    return i + j;
}

int main()
{
  const int size = 256;

  double sum = 0;

//will use openmp
#pragma omp parallel for
for(int i = 0; i < size; i = i + 1)
{
    for(int j = 0; j < size; j=j+1)
    {
        if(i != j)
        {
            double increment = f(i,j);
            #pragma omp critical
            sum = sum + increment;
        }
    }

}

cout << "sum = " << sum << endl;


//not using openmp
sum = 0;
for(int i = 0; i < size; i = i + 1)
{
    for(int j = 0; j < size; j=j+1)
    {
        if(i != j)
        {
            sum = sum + f(i,j);
        }
    }

}

cout << "sum = " << sum << endl;  

 }