假设我有一个稀疏的矩阵,除了对角线上的块(固定大小)。
Eigen::SparseMatrix<float> lhs;
lhs约为2%非稀疏,但可能非常大。然后,假设我有一个向量:
Eigen::MatrixXf rhs = Eigen::MatrixXf::Random(SomeSz, 1);
目前,我们假设它很密集。
我想有效地计算:
result.noalias() = lhs * rhs;
如果我要使用-O3 -march = native -mtune = native(使用Clang)进行编译,这会产生最佳结果吗?
另外,如果rhs稀疏怎么办:
Eigen::SparseMatrix<float> rhs; rhs.resize(SomeSz, 1); rhs.reserve(SomeSz/SomeFactor);
时:
result = lhs * rhs;
仍然是最佳的/次优的?
我想我要问的是Eigen是否会利用块稀疏结构并只执行必要的计算。
答案 0 :(得分:0)
首先,在rhs的密集情况下,如果rhs是一个向量,那么请使用VectorXf
告诉Eigen。然后,使用Eigen 3.3,您可以通过使用-fopenmp
进行编译并使用lhs
的行主存储来利用多线程。
在稀疏的情况下,是的Eigen将考虑lhs和rhs的稀疏性。与具有密集rhs的rhs.nonZeros()*average_nnz_per_col_of_lhs
形成鲜明对比,复杂度实际上为rhs.size()*average_nnz_per_col_of_lhs
。因此,如果rhs非常稀疏,那么它可能值得一试。只考虑lhs的有用列。在这种情况下,最好保留lhs column-major。