如何将for循环转换为STL for_each语句

时间:2010-03-09 18:02:27

标签: c++ stl parallel-processing

我想将for循环转换为STL std :: for_each循环。

 bool CMyclass::SomeMember()
 {
    int ii;
        for(int i=0;i<iR20;i++)
            {
              ii=indexR[i];
              ishell=static_cast<int>(R[ii]/xStep);
              theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
              al2[ishell] += massp*cos(fm*theta);
            }
 }

实际上我打算使用g ++ 4.4中的并行STL

 g++ -D_GLIBCXX_PARALLEL -fopenmp

允许在没有更改的情况下并行运行代码,如果代码是在标准STL库中编写的。

4 个答案:

答案 0 :(得分:5)

你需要将循环体分离成单独的函数或函子;我假设所有未声明的变量都是成员变量。

void CMyclass::LoopFunc(int ii)  {
    ishell=static_cast<int>(R[ii]/xStep);
    theta=atan2(data->pPOS[ii*3+1],
    data->pPOS[ii*3]);
    al2[ishell] += massp*cos(fm*theta);
}

bool CMyclass::SomeMember()  { 
    std::for_each(&indexR[0],&indexR[iR20],std::tr1::bind(&CMyclass::LoopFunc,std::tr1::ref(*this));
}

答案 1 :(得分:1)

class F {
   public:
   void operator()(int ii) {
              ishell=static_cast<int>(R[ii]/xStep);
              theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
              al2[ishell] += massp*cos(fm*theta);
   } 
   F(int[] r): //and other parameters should also be passed into the constructor
      r_(r) {}
   void:
   int[] r_; // refers to R[ii] array
   // and other parameters should also be stored
};

F f(R); // pass other parameters too  
for_each(&indexR[0], &indexR[iR20], f);

然而,使用这种“自动并行化”可能不是一个好主意,因为你需要记住每个并行计算的粒度 - 我不确定编译器考虑粒度的程度。

答案 2 :(得分:1)

你不能将循环体分成仿函数,并假设它将被并列化,因为你在循环体内有太多的依赖。 只有在没有全局数组或指针的情况下,Cycle才能并行运行。如果您提供完整的功能体,那么我们可以考虑如何将其更改为并行版本。

答案 3 :(得分:0)

您需要将循环体转换为函数或函子。那里有很多未声明的变量,所以我不能轻易告诉如何分离出循环体。这是对它的抨击:

class DoStuff
{
  int* R;
  int xStep;
  Data* data;
  double massp;
  double fm;
  double* al2;
public:
  DoStuff(int* R_, int xStep_, Data* data_, double massp_, double fm_, double* al2_) :
    R(R_), xStep(xStep_), data(data_), massp(massp_), fm(fm_), al2(al2_) {}

  void operator()(int ii)
  {
     int ishell = static_cast<int>(R[ii]/xStep);
     double theta = atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
     al2[ishell] += massp*cos(fm*theta);
  }
};

for_each(indexR, indexR+iR20, DoStuff(R, xStep, data, massp, fm, al2));