犰狳图书馆看起来很慢

计算科学 矩阵 C++
2021-12-02 19:39:24

我一直在尝试为电磁学的 FDTDS 系统构建 C++ 项目。我已经实现了一个类 [见下文],我使用 Armadillo 库将其称为网格。字段 Ex、Ey、Ez、Hx、Hy、Hz 的 3D 矩阵 {Cubes} 被声明为类的私有成员。这些 3D 矩阵的大小由构造函数决定。在程序的具体细节部分,这些字段由公共函数更新 [见下文] void updateE(void) 和 void updateH(void)。该程序运行良好,但速度极慢。我用一个计时器进行了实验,发现对 3D 矩阵的各个元素的访问是 2e-5 的顺序。在我用 C 语言构建的一个类似项目中,但使用宏和动态内存分配和指针,我可以更快地获得大约一千秒的访问时间。我一定做错了什么。我对犰狳和 C++ 都是新手。

#include <armadillo>

using namespace arma;

class mesh
{
  private:

    //size of mesh
    int SizeX;
    int SizeY;
    int SizeZ;

   /* declaration of Matrices/Cubes */
   cube  Hx;
   ....
    ....


public:
   mesh(int sizex, int sizey, int sizez); //construct mesh and init values
   void updateE(void);         // Update Electric field
   void updateH(void);         // Update Magnetic field
   .......


};


mesh::mesh( int sizex, int sizey, int sizez)
{
    // allocate size
    SizeX= sizex;
    SizeY= sizey;
    SizeZ= sizez;

    /* memory allocation and zeroed*/

    Hx      = zeros<cube>( SizeX, SizeY - 1, SizeZ - 1);

    ........




}


void mesh::updateH(void) {
  int mm, nn, pp;

   for (mm = 0; mm < SizeX; mm++)
      for (nn = 0; nn < SizeY - 1; nn++)
        for (pp = 0; pp < SizeZ - 1; pp++)
            Hx(mm, nn, pp) = Chxh(mm, nn, pp) * Hx(mm, nn, pp) +
            Chxey(mm, nn, pp) * (Ey(mm, nn, pp + 1) - Ey(mm, nn, pp) ) -
            Chxez(mm, nn, pp) *(Ez(mm, nn + 1, pp) - Ez(mm, nn, pp));

   for (mm = 0; mm < SizeX - 1; mm++)
      for (nn = 0; nn < SizeY; nn++)
        for (pp = 0; pp < SizeZ - 1; pp++)
            Hy(mm, nn, pp) = Chyh(mm, nn, pp) * Hy(mm, nn, pp) +
            Chyez(mm, nn, pp) * (Ez(mm + 1, nn, pp) - Ez(mm, nn, pp)) -
            Chyex(mm, nn, pp) * (Ex(mm, nn, pp + 1) - Ex(mm, nn, pp));

   for (mm = 0; mm < SizeX - 1; mm++)
      for (nn = 0; nn < SizeY - 1; nn++)
        for (pp = 0; pp < SizeZ; pp++)
            Hz(mm, nn, pp) = Chzh(mm, nn, pp) * Hz(mm, nn, pp) +
            Chzex(mm, nn, pp) * (Ex(mm, nn + 1, pp) - Ex(mm, nn, pp)) -
            Chzey(mm, nn, pp) * (Ey(mm + 1, nn, pp) - Ey(mm, nn, pp));


 return;
 } /* 
1个回答

我终于获得了与 C++/Armadillo 和 C/arrays 相当的速度。

  1. 首先,我按照 Daniel 的建议将循环的顺序切换为列优先顺序。

  2. 其次,我将循环的计数器从 int 更改为 uword。

  3. 最后我使用函数 .at() 来禁用绑定检查。