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++ 中最有效的矩阵表示是啥?的主要内容,如果未能解决你的问题,请参考以下文章