我正在使用C++创建一个有限元分析例程,并尝试使用Open MP来并行化我代码中的一些'for‘循环。
我有一个名为Elements的结构数组,数组的每个部分都包含一个结构,其中包含该特定元素的所有信息。需要的一些信息是每个元素的刚度矩阵(在下面的代码中称为kt )。然后将其组装成整个系统的全局刚度矩阵。
单元刚度矩阵的计算是相当复杂和冗长的,所以我认为我可以通过并行它的计算获得一些很好的速度增益。
当与Open MP相关的所有内容都被注释掉时,下面的代码工作得很好,但当我没有同时写入元素,并且kt和Elementsi (第i个元素)对于正在使用它们的线程是私有的时,它就会失败。
我将Armadillo用于矩阵代数,所以这就是'mat‘的意思。
我对C++还很陌生,所以任何帮助都将不胜感激。
mat KtCalc(struct Element Elements[],mat Nodes,double ngamma,double nbeta,double hhtalpha, int nel, double dt)
//Stiffness matrix calculation routine
{
int nn=Nodes.n_rows;
mat Kt(nn*6, nn*6, fill::zeros);
int i;
struct Element Elementi;
mat kt;
#pragma omp parallel private(Elementi,kt) shared(nel,i,hhtalpha,ngamma,nbeta,dt,Elements)
{
#pragma omp for
for(i=0;i<nel;i++)
{
#pragma omp critical(dataupdate)
{
Elementi=Elements[i];
}
kt=KtEl(Elementi, ngamma, nbeta, hhtalpha, dt);
#pragma omp critical(dataupdate)
{
Elements[i].kt=kt;
}
}
}
for(int k=0;k<nel;k++){
//Use the stuff calculated above in a non parallel way to calculate Kt
}
return Kt;
}发布于 2014-06-06 20:26:02
您的问题是forloop的i共享减速。在cpp中,你可以在任何地方声明变量。下面的代码是等效的,应该可以工作:
mat KtCalc(struct Element Elements[],mat Nodes,double ngamma,double nbeta,double hhtalpha, int nel, double dt)
//Stiffness matrix calculation routine
{
int nn=Nodes.n_rows;
mat Kt(nn*6, nn*6, fill::zeros);
#pragma omp parallel for
for(int i=0;i<nel;i++)
{
Elements[i].kt=KtEl(Elements[i], ngamma, nbeta, hhtalpha, dt);
}
for(int k=0;k<nel;k++){
//Use the stuff calculated above in a non parallel way to calculate Kt
}
return Kt;
}此外,还允许同时修改数组的元素,只要您确定永远不会修改相同的元素(这是因为您只接触到了i的th元素)。critical部分是不必要的。
顺便说一句,您通常希望变量声明得越晚越好。在顶部声明它们是旧的c风格。尽可能晚地声明它们means
https://stackoverflow.com/questions/24081424
复制相似问题