C++ 中最有效的矩阵表示是啥?

Posted

技术标签:

【中文标题】C++ 中最有效的矩阵表示是啥?【英文标题】:What is the most efficient matrix representation in C++?C++ 中最有效的矩阵表示是什么? 【发布时间】:2016-12-14 11:10:11 【问题描述】:

希望这个问题不是OT。

我正在使用来自不同实现的VLFeat implementation 和SIFT 描述符来实现VLAD 编码器以比较它们(OpenCV、VLFeat、OpenSIFT)。

这应该是 C++ 中的高性能应用程序(我知道 SIFT 效率很低,我正在实现它的并行版本)。

现在,VLAD 希望将指向一组连续描述符(数学向量)的指针作为输入。关键是通常这个 SIFT 描述符被表示为一个矩阵,所以更容易管理它们。

所以假设我们有一个 3 维的 3 个描述符的矩阵(为了简单起见,我使用这些数字,实际上它是 128 维的数千个描述符):

1 2 3
4 5 6
7 8 9

我需要使用指向:

1 2 3 4 5 6 7 8 9

一个简单的解决方案是将描述符保存在cv::Mat m 对象中,然后将m.data 传递给vl_vlad_encode

但是我不知道cv::Mat 是否是一种有效的矩阵表示。例如,Eigen::Matrix 是另一种选择(我认为使用此对象很容易获得上面的表示),但我不知道哪种实现更快/更有效,或者是否有任何其他原因,因为我应该更喜欢一个的另一个。

另一种可能的选择是使用std::vector<std::vector<float>> v,但我不知道如果使用v.data(),我会获得上面的表示而不是: 1 2 3 *something* 4 5 6 *something* 7 8 9

显然*something* 会搞砸vl_vlad_encode

欢迎提出任何其他建议!

【问题讨论】:

float [9]?同意以列或行为主的约定,然后您可以将所有内容连续布置为一列或一排。 @AndonM.Coleman 想解释一下 float[9] 和 float[3][3] 之间的区别吗?它们都是连续的,并且列/行约定对于两者都是可以更改的。 我忘了说矩阵维度是在运行时决定的,所以使用std::vector<float> v然后v.resize(dim)(或v.reserve(dim))可能是一个更好的解决方案,在这种情况下dim=9 . 除非你做了一些奇怪的事情(详见here),Mat 中的数据是连续的。您可以将Mat 视为float*(或其他类型)的轻量级包装器,它允许更轻松地访问数据。所以它和指针一样高效,但有一些不错的抽象。 正确。您还可以使用this 提高对文件的写入/读取性能。使用 xml 或 yaml 可能太慢了。如果您不需要人类可读的文件,您可以使用链接中的函数以二进制形式保存 【参考方案1】:

除非你做了一些奇怪的事情(详见here),Mat 中的数据保证是连续的。您可以将Mat 视为float*(或其他类型)的轻量级包装器,可以更轻松地访问数据。所以它和指针一样高效,但有一些不错的抽象。

如果您需要高效地从文件加载/保存,可以使用matread and matwrite 以二进制格式保存Mat

【讨论】:

【参考方案2】:

std::vector<std::vector<float>> v 不付出努力就不会表现得很好,因为内存不会是连续的。

一旦你的内存是连续的,无论是 float[]、float[][] 还是 std::array/vector,它的性能将取决于你如何迭代你的矩阵。如果是随机访问,那差别不大;如果您要迭代所有列,那么最好将数据按列而不是按行分组。

【讨论】:

以上是关于C++ 中最有效的矩阵表示是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中对大输入实现矩阵的最有效方法?

c++中scanf的表示是啥[关闭]

块拼图求解 C++ 算法

矩阵的几何意义是啥

在 Visual Studio C++ 中,内存分配表示形式是啥?

matlab中,矩阵开根号的语句是啥?