Нужен ли конструктор копирования для моего распараллеливания OpenMP?

Я столкнулся с ошибками, когда я распараллеливал свою функцию ниже.

bool
CMolecule::computeForces_twobody(vector<CMolecule*> &mols,
vector<CPnt> & force, vector<CPnt> & torque)
{
if(mols.size() == 1 ) return true;
int nmol=mols.size();
int M2=nmol*(nmol-1)/2;vector<CMolecule*> twomols;vector<CPnt> force2b(nmol),torque2b(nmol);vector<CSphereIDPair> dimer;

CPnt forcetemp,torquetemp;

for(int i=0;i<nmol;i++)
for(int j=i+1;j<nmol;j++)
{
dimer.push_back(CSphereIDPair(i,j));
}

#pragma omp parallel for private(twomols, forcetemp, torquetemp)
for(int i=0;i<M2;i++)
{
twomols.push_back(new CMolecule(*mols[dimer[i].is]));
twomols.push_back(new CMolecule(*mols[dimer[i].js]));
bool bInterXFS =  CMolecule::generateInterXFormsForPolarize_LowMemory(twomols);
if(! bInterXFS )
cout <<"error in generateInterXFormsForPolarize_LowMemory"<<endl;
CMolecule::polarize_mutual(twomols,false, 1000);

twomols[0]->computeMol_Force_and_Torque(forcetemp,torquetemp);
force2b[dimer[i].is]+=forcetemp;
torque2b[dimer[i].is]+=torquetemp;

twomols[1]->computeMol_Force_and_Torque(forcetemp,torquetemp);
force2b[dimer[i].js]+=forcetemp;
torque2b[dimer[i].js]+=torquetemp;

twomols.clear();
}

for(int i=0;i<nmol;i++)
{
force[i]=force2b[i];
torque[i]=torque2b[i];
}

return true;
}

Серийный код может работать нормально. Тем не менее, при параллельном запуске программы произошел сбой в функции polarize_mutual и был создан файл дампа ядра (к сожалению, я не нашел никакой полезной информации из файла дампа ядра). Поэтому я подозреваю, что с моей операцией копирования может быть что-то не так.

        twomols.push_back(new CMolecule(*mols[dimer[i].is]));
twomols.push_back(new CMolecule(*mols[dimer[i].js]));

Я не видел ничего плохого, но сомневаюсь, что эта операция копирования может быть мелкой копией. Это связано с тем, что объекты класса CMolecule строятся с использованием конструктора, который содержит множество указателей.

  CMolecule::CMolecule(int moltype, CPnt rcen, const vector<CPnt> &cens, const vector<double> &radii,
const vector<double> &chg, const vector<CPnt> &cpos, double idiel,
const vector<REAL*> &iMats, REAL intraRcutoff,
const vector<vector<CPnt> > &SPxes, const vector<int> &nSPx,
const vector<vector<int> >&neighs,
const vector< vector<int> > &intraPolLists_near,
const vector<CMulExpan*> &Fself, const vector<CMulExpan*> &Hself,
const vector<CLocalExpan*> & LFs_intraSelf, const vector<CLocalExpan*>  &LHs_intraSelf,
const vector<CLocalExpan*> & LFs_intraSelf_far, const  vector<CLocalExpan*> &LHs_intraSelf_far,
const vector<vector<REAL> > &qSolvedFself,
const vector<vector<REAL> > &qSolvedHself,
const vector<double> &totalFself, const vector<double> &totalHself,
const vector<CMolCell> &molcell)
: m_rot(false), m_p(N_POLES), m_idiel(idiel), m_bKappa(false),  m_bAggregateM(false), m_moltype(moltype),
m_molcells(molcell)

Нужно ли писать конструктор копирования для класса CMolecule, чтобы сделать глубокое копирование?

0

Решение

Тебе действительно нужен вектор STL twomols только для хранения ссылок на 2 CMolecule? Ваша реализация кажется довольно расточительной из циклов процессора. Я думаю, что что-то в этом роде может быть проще для компилятора оптимизировать:

#pragma omp parallel for private(twomols, forcetemp, torquetemp)
for(int i=0;i<M2;i++)
{
const CMolecule& a = mols[dimer[i].is];
const CMolecule& b = mols[dimer[i].js];
CMolecule::polarize_mutual(a, b, false, 1000);
// (...)
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector