Eigen:按行计算矩阵的范数,比在向量上迭代计算它们要慢

Posted

技术标签:

【中文标题】Eigen:按行计算矩阵的范数,比在向量上迭代计算它们要慢【英文标题】:Eigen: Computing norms of matrix rowwise, is slower than computing them iteratively on vectors 【发布时间】:2018-03-01 09:26:04 【问题描述】:

我正在尝试使用 Eigen 加速向量范数的计算。

尝试了两种方式:

方式一:将向量分别存储在一个数组中(std::vector)

std::vector<Eigen::Matrix<double, 1, VECTOR_SIZE>> my_vectors(num_vectors);
Eigen::Matrix<double, Eigen::Dynamic, 1> norms(num_vectors, 1);
for (int i = 0 ; i < my_vectors.size() ; i++) 
    norms(i, 0) = my_vectors[i].norm();

方式2:将向量存储为同一矩阵的行并使用行范数

Eigen::Matrix<double, Eigen::Dynamic, VECTOR_SIZE> my_vectors(num_vectors, VECTOR_SIZE);
Eigen::Matrix<double, Eigen::Dynamic, 1> norms = my_vectors.rowwise().norm();

我很惊讶地发现 Way1 很慢,而 Way2 更慢。

我做错了吗?有没有办法更快地计算规范?

在我做的另一个测试中,向量减法也是如此。对单独的向量进行迭代,从每个向量中减少相同的向量,比将所有向量存储为矩阵行并使用 .rowwise() - vector_to_subtract

更快

【问题讨论】:

您使用的是哪个 Eigen 版本、哪个编译器、什么编译标志?而num_vectors一般有多大,你有没有初始化my_vectors的内存? 【参考方案1】:

来自https://eigen.tuxfamily.org/dox/group__TopicStorageOrders.html

如果未指定存储顺序,则 Eigen 默认以列为主存储条目。如果使用方便的 typedef(Matrix3f、ArrayXXd 等)之一,情况也是如此。

我最好的猜测是内存访问问题:rowwise() 可能在内存中进行了一堆“跳过”,即不读取连续区域 - 而单独存储每一行​​不会遇到这个问题。

警告:虽然我是出于好意写下我的答案,但我无法自己测试它,而且显然它会进一步减慢速度。感谢SomethingSomething 测试这个想法。

【讨论】:

所以我将矩阵定义从Eigen::Matrix&lt;double, Eigen::Dynamic, VECTOR_SIZE&gt; 更改为Eigen::Matrix&lt;double, Eigen::Dynamic, VECTOR_SIZE, Eigen::RowMajor&gt;。等我能再检查一下性能,我会告诉你它是否真的解决了问题 不幸的是它没有帮助..甚至变慢了...我终于坚持使用std::vector 解决方法并成功地使用多线程加速了我的流程(当我需要制作一个很多这样的逐行计算。将它们分成最多 16 个线程就可以了)

以上是关于Eigen:按行计算矩阵的范数,比在向量上迭代计算它们要慢的主要内容,如果未能解决你的问题,请参考以下文章

向量和矩阵的范数Ax=b的误差分析

《数值分析》-- 向量和矩阵的范数Ax=b的误差分析

《数值分析》-- 向量和矩阵的范数Ax=b的误差分析

数值分析 向量的范数 证明 x-y

向量的范数

SVM&范数&SVD