防止 Eigen 在使用 Eigen::Block 时创建临时对象

问题描述 投票:0回答:0

我正在使用 Eigen 库及其块操作来计算矩阵 B 和 C 之间的矩阵乘法,结果保存到矩阵 A 中。B 有 N 行和 M 列,C 有 M 行和 P cols,其中 P 是 1 到 max_cols 之间的数字。所以 A 将有 N 行和 P 列。我预先分配矩阵 A、B、C,然后进入一个迭代算法,我需要修改它们的值并计算乘法。我需要这最后一步尽可能快。由于我无法提前知道P,但我知道max_cols,我预先为A和C分配了max_cols cols然后我计算矩阵乘法考虑我在该迭代中需要的cols数量(P)使用块操作:

 A.block(0,0,N,P).noalias() = B*C.block(0,0,M,P);

为了避免创建临时对象,我使用

noalias()
作为矩阵 A。我还使用
Eigen::internal::set_is_malloc_allowed(false)
来检查是否没有创建临时对象。

我看到当 N 和 M 等于 150 时程序不会因为

EIGEN_RUNTIME_NO_MALLOC
断言而停止,而当 N 和 M 等于 180 时程序会停止。 有人可以解释为什么吗?你能建议我如何解决问题或以其他方式完成我的任务吗?

下面是重现问题的简化代码:

#define EIGEN_RUNTIME_NO_MALLOC 
#include <Eigen/Dense>
#include <eigen3/Eigen/Eigen>

int main(int argc, char** argv)
{
  uint N, M, P, max_cols;

  // Initial allocation
  N = 150;
  M = 150;
  P = 10;
  max_cols = 50;

  Eigen::MatrixXd B = Eigen::MatrixXd::Random(N, M);
  Eigen::MatrixXd C = Eigen::MatrixXd::Random(M, max_cols);
  Eigen::MatrixXd A(N,max_cols);

  // 
  //Here some code that set the values of the first P columns of C that I will consider into the multiplication
  //

  // This code should be executed as fast as possible without temporaries
  Eigen::internal::set_is_malloc_allowed(false);

  A.block(0,0,N,P).noalias() = B*C.block(0,0,M,P);  // no assertion

  Eigen::internal::set_is_malloc_allowed(true);
  // until here

  std::cout<<"first multiplication OK"<<std::endl;

  N = 180;
  M = 180;

  Eigen::MatrixXd B2 = Eigen::MatrixXd::Random(N, M);
  Eigen::MatrixXd C2 = Eigen::MatrixXd::Random(M, max_cols);
  Eigen::MatrixXd A2(N,max_cols);

  // 
  //Here some code that set the values of the first P columns of C that I will consider into the multiplication
  //

  // This code should be executed as fast as possible without temporaries
  Eigen::internal::set_is_malloc_allowed(false);

  A2.block(0,0,N,P).noalias() = B2*C2.block(0,0,M,P);  // assertion

  Eigen::internal::set_is_malloc_allowed(true);
  // until here

  std::cout<<"second multiplication OK"<<std::endl;

  return 0;
} 
c++ eigen
© www.soinside.com 2019 - 2024. All rights reserved.