Я хотел бы преобразовать мой для цикла к станд. 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.
Вам нужно выделить тело цикла в отдельную функцию или функтор; Я предположил, что все необъявленные переменные являются переменными-членами.
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));
}
Вы не можете просто разделить тело цикла на функтор и предположить, что оно будет параллелизировано, потому что у вас слишком много зависимостей внутри тела цикла. Цикл сможет работать параллельно, только если у вас нет глобальных массивов или указателей. Если вы предоставите полное тело функции, тогда мы сможем подумать, как изменить его на параллельную версию.
Вам нужно будет преобразовать тело цикла в функцию или функтор. Там много необъявленных переменных, поэтому я не могу легко сказать, как выделить тело цикла. Вот укол:
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));
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);
Однако использование этого «автоматического распараллеливания» может быть не очень хорошей идеей, поскольку вам нужно помнить о размере каждого параллельного вычисления - я не уверен, насколько хорошо компилятор учитывает размер зерна.