并行化' for'使用Open MP循环读取和写入数据结构

时间:2014-06-06 12:04:45

标签: c++ parallel-processing

我正在使用C ++创建一个有限元分析例程,并且我尝试使用Open MP来并行化一些' for'在我的代码中循环。

我有一个名为Elements的结构数组,数组的每个部分都包含一个结构,其中包含该特定元素的所有信息。所需的一些信息是每个元素的刚度矩阵(在下面的代码中称为kt)。然后将其组装成整个系统的整体刚度矩阵。

元素刚度矩阵的计算非常复杂且冗长,所以我认为通过并行计算可以获得一些好的速度增益。

下面的代码在与Open MP相关的所有内容都被注释掉时工作正常,但是当它不是因为我不是同时写入Elements并且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;
}

1 个答案:

答案 0 :(得分:1)

你的问题是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

  • 它使RAII(资源获取初始化)更容易。
  • 它使变量的范围保持紧张。这可以让优化器更好地工作。