我的OpenMP并行化需要一个复制构造函数吗?

时间:2013-04-30 05:35:12

标签: c++ pointers clone openmp copy-constructor

我在下面的函数并行化时遇到了错误。

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'编写复制构造函数来执行深层复制?

1 个答案:

答案 0 :(得分:0)

你真的需要twomols STL向量来保存对2个CMolecule的引用吗?您的实现似乎非常浪费CPU周期。我想这些内容可能更容易让编译器进行优化:

#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);
   // (...)
}