【问题标题】:Eigen Efficient Passing of Matrices矩阵的特征有效传递
【发布时间】:2018-09-08 20:48:40
【问题描述】:

我在我的应用程序中使用 Eigen,通过分析我找到了代码 类似于以下成为瓶颈。问题是内存 在数据传递给使用时复制(见下文)。

从代码中可以看出,用于 ​​matmat 函数的“数据”可以有 两个来源之一,一个私有存储在 SMM 类中,而另一个 是动态生成的。这种分裂对我来说是必要的 应用程序,但它很难优化。是否只是来源 从数据的内部向量来看,在我看来 const Eigen::Refs 会 成为一个简单的解决方案。也许是由于我的代码编写方式,但是 复制省略似乎没有我希望的那样做。一世 考虑使用 shared_ptr 来防止复制矩阵(其中 可能很大),但我不确定这是否是正确的方向。

需要注意的是matmat的结果永远不需要存储,它是 仅在 Eigen 表达式中用作临时变量

在这种情况下如何有效地传递矩阵?

以下代码是我正在使用的设置的简化。

#include <Eigen/Dense>
#include <Eigen/StdVector>
#include <iostream>

using namespace Eigen;
typedef MatrixXd MMatrix;

enum class Storage {Normal, On_The_Fly };

MMatrix matrixGen(int additional_data) {
  return additional_data *  MMatrix::Random(5, 5);
}

class SMM {
  private:
    std::vector<MMatrix, Eigen::aligned_allocator<MMatrix> > data_;

   //Provides controlled access to the data
    MMatrix get_data(int i, Storage mem, int additional_data = 0) {
      if (mem != Storage::On_The_Fly) {
        return data_[i];
      }
      else {
        return matrixGen(additional_data);
      }
    }
  public:
   // Only a placeholder constructor, in my actual program the building
   // is significantly more complex, and doesn't build the data immediately
   SMM(Storage mem) {
     if (mem == Storage::Normal) {
       for (int i = 0; i < 5; i++) {
         data_.emplace_back(matrixGen(5));
       }
     }
    }


    //Similar to a matrix * matrix product
    MMatrix matmat(const MMatrix& A, int index, Storage mem, int additional_data = 0) {
      if (mem == Storage::On_The_Fly) {
        return this->get_data(index, mem, additional_data) * A;
      }
      else {
        return this->get_data(index, mem) * A;
      }
    }
};

int main() {
  Storage mem1 = Storage::Normal;
  Storage mem2 = Storage::On_The_Fly;
  SMM smm1 = SMM(mem1);
  SMM smm2 = SMM(mem2);
  MMatrix A = MMatrix::Random(5, 5);

  MMatrix B = MMatrix::Random(5, 5);
  MMatrix C = MMatrix::Random(5, 5);

  B += smm1.matmat(A, 2, mem1);
  C += smm2.matmat(A, 2, mem2, 5);
  std::cout << B << std::endl << std::endl;
  std::cout << C << std::endl;
}

【问题讨论】:

    标签: c++ performance matrix eigen eigen3


    【解决方案1】:

    一个简单的解决方案是使用缓存成员变量:

    class SMM {
      ...
      MMatrix cache_;
      const MMatrix& get_data(int i, Storage mem, int additional_data = 0) {
        if (mem != Storage::On_The_Fly) { return data_[i]; }
        else {
          matrixGenInPlace(additional_data,cache_);
          return cache_;
        }
      }
      ...
    };
    

    【讨论】:

    • 这很有效,尽管我在使用 OpenMP 进行多线程处理时使用了缓存向量(遵循本征分配建议)进行了修改(超出了问题的范围),其中每个线程正在做一个单独的垫子。谢谢!
    • 顺便说一句,对于动态分配的 Eigen 矩阵,无需使用对齐分配器。只有 Matrix4d、Vector4f 等固定大小的才需要。
    猜你喜欢
    • 1970-01-01
    • 2017-08-27
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 2013-09-25
    • 2018-07-10
    • 1970-01-01
    相关资源
    最近更新 更多