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