[英]OpenMP reduction with overloaded operator
我正在嘗試使用OpenMP在以下函數中並行化循環
void CEnergymulti::forcetwobody(vector<CMolecule*> m_mols,CPnt force0,CPnt torque0)
{
const int nmol=m_mols.size();
vector<CMolecule*> twomols(2);
CPnt forcetemp,torquetemp;
twomols.clear();
force0.zero();
torque0.zero();
forcetemp.zero();
torquetemp.zero();
#pragma omp parallel for reduction(+:force0,torque0) private(twomols)
for(int j=1;j<nmol;j++)
{ twomols.push_back(m_mols[0]);
twomols.push_back(m_mols[j]);
CMolecule::polarize_mutual(twomols,false, 1000);
twomols[0]->computeMol_Force_and_Torque(forcetemp,torquetemp);
force0+=forcetemp;
torque0+=torquetemp;
forcetemp.zero();
torquetemp.zero();
twomols.clear();
}
REAL converter=COUL_K*IKbT;
force0*=converter;
torque0*=converter;
return;
}
當我編譯代碼時,它給出以下消息:
EnergyD_multi.cpp: In static member function ‘static void
CEnergymulti::forcetwobody(std::vector<CMolecule*,
std::allocator<CMolecule*> >, CPnt, CPnt)’: EnergyD_multi.cpp:226:
error: ‘torque0’ has invalid type for ‘reduction’
EnergyD_multi.cpp:226: error: ‘force0’ has invalid type for
‘reduction’
我知道變量'force0'和'torque0'既不是雙重或整數類型的數據,而是類型'CPnt',這是一個定義為表示空間中三維向量的類。 對於類'CPnt',運算符'+'和' - '已經由運算符重載定義。 所以我的問題是:OpenMP的減少是否真的無法處理這樣的重載運算符? 有沒有其他方法可以將此循環與OpenMP並行化而不減少'force0'和'torque0'的每個組件?
非常感謝。
確實,OpenMP減少無法處理這樣的重載運算符。 但是,還有另一種選擇。 重寫OpenMP減少的一種方法是使用nowait
和atomic
參數。 http://bisqwit.iki.fi/story/howto/openmp/#ReductionClause 。這和正常方式一樣快。
如果將atomic
替換為critical
,則可以使用更復雜的重載運算符。 這並不像使用atomic
那么快,但它在我的經驗中仍然有效。
我這樣做了所以我可以使用同時操作4或8個浮點數的運算符(使用SEE或AVX)。 使用SSE / AVX進行OpenMP減少
編輯:我改變了你的代碼,以反映我認為你想做的事情。
void CEnergymulti::forcetwobody(vector<CMolecule*> m_mols,CPnt force0,CPnt torque0)
{
const int nmol=m_mols.size();
force0.zero();
torque0.zero();
#pragma omp parallel
{
CPnt force0_private;
CPnt torque0_private;
force0_private.clear();
torque0_private.clear();
#pragma omp for nowait
for(int j=1;j<nmol;j++)
{
CPnt forcetemp,torquetemp;
forcetemp.zero();
torquetemp.zero();
vector<CMolecule*> twomols(2);
twomols.clear();
twomols.push_back(m_mols[0]);
twomols.push_back(m_mols[j]);
CMolecule::polarize_mutual(twomols,false, 1000);
twomols[0]->computeMol_Force_and_Torque(forcetemp,torquetemp);
force0_private+=forcetemp;
torque0_private+=torquetemp;
}
#pragma omp critical
{
force0 += force0_private;
torque0 += torque0_private;
}
}
REAL converter=COUL_K*IKbT;
force0*=converter;
torque0*=converter;
return;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.