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

Parallelise 'for' loop reading and writing to data structure with Open MP

本文关键字:数据结构 读取 for Open MP 并行 使用 循环      更新时间:2023-10-16

我正在使用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;
}

您的问题是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个元素(。因此critical部分是不必要的。

附带说明一下,您通常希望尽可能晚地声明变量。在顶部声明它们是旧的c风格。尽可能晚地宣布它们意味着:

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