Как преобразовать для цикла в STL for_each оператор

Я хотел бы преобразовать мой для цикла к станд. STL:: цикл 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);
            }
 }

На самом деле я планировал использовать параллельный STL от g ++ 4.4

 g++ -D_GLIBCXX_PARALLEL -fopenmp

который является, позволяют выполнять код параллельно без изменений, если код написан в стандартной библиотеке STL.

5
задан Benjamin 8 February 2014 в 00:04
поделиться

4 ответа

Вам нужно выделить тело цикла в отдельную функцию или функтор; Я предположил, что все необъявленные переменные являются переменными-членами.

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));
}
5
ответ дан 14 December 2019 в 08:48
поделиться

Вы не можете просто разделить тело цикла на функтор и предположить, что оно будет параллелизировано, потому что у вас слишком много зависимостей внутри тела цикла. Цикл сможет работать параллельно, только если у вас нет глобальных массивов или указателей. Если вы предоставите полное тело функции, тогда мы сможем подумать, как изменить его на параллельную версию.

1
ответ дан 14 December 2019 в 08:48
поделиться

Вам нужно будет преобразовать тело цикла в функцию или функтор. Там много необъявленных переменных, поэтому я не могу легко сказать, как выделить тело цикла. Вот укол:

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));
0
ответ дан 14 December 2019 в 08:48
поделиться
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);

Однако использование этого «автоматического распараллеливания» может быть не очень хорошей идеей, поскольку вам нужно помнить о размере каждого параллельного вычисления - я не уверен, насколько хорошо компилятор учитывает размер зерна.

1
ответ дан 14 December 2019 в 08:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: