什么是C++中最高效的矩阵表示方法?

5

我希望这个问题不是离题的。

我正在使用VLAD编码器实现一个高性能的应用程序,使用不同实现的VLFeat implementationSIFT描述符进行比较(OpenCV、VLFeat、OpenSIFT)。

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

现在,VLAD需要作为输入指向一组连续描述符(数学向量)的指针。问题在于,通常这些SIFT描述符被表示为矩阵,因此更容易管理。

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

1 2 3
4 5 6
7 8 9

我需要将指针传递给vl_vlad_encode进行馈送。

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 混乱。
任何其他建议都非常受欢迎!

2
float [9]是什么意思?先同意使用列主序或行主序约定,然后您可以将所有内容连续地布局在一列或一行之后。 - Andon M. Coleman
@AndonM.Coleman,能否解释一下float[9]和float[3][3]之间的区别?它们都是连续的,对于两者来说,列/行约定都是可以改变的。 - UKMonkey
我忘了说矩阵的维度是在运行时决定的,因此使用 std::vector<float> v 然后 v.resize(dim)(或 v.reserve(dim))可能是更好的解决方案,在这种情况下 dim=9 - justHelloWorld
1
除非你做一些奇怪的事情(详见这里),否则Mat中的数据是连续的。你可以把Mat看作是一个轻量级的float*(或其他类型)包装器,它允许更容易地访问数据。因此,它与指针一样高效,但具有一些不错的抽象特性。 - Miki
1
可以的。你也可以使用这个链接来提高文件的写入/读取性能。使用xml或yaml可能会太慢了。如果你不需要可读性强的文件,可以使用链接中的函数以二进制形式保存。 - Miki
显示剩余3条评论
2个回答

5
除非你做一些奇怪的事情(详见这里),否则Mat中的数据保证是连续的。你可以认为Mat是一个轻量级的包装器,可以更方便地访问float*(或其他类型)的数据。因此,它与指针一样高效,但具有一些不错的抽象特性。
如果您需要有效地从文件中加载/保存,可以使用matreadmatwrite以二进制格式保存Mat

2

std::vector<std::vector<float>> v 如果没有一些努力,性能将不会很好,因为内存不是连续的。

一旦您的内存是连续的,无论是 float[]、float[][] 还是 std::array/vector,它的性能取决于您如何迭代矩阵。如果是随机访问,那么几乎没有区别;如果您每次都要遍历所有列,则最好按列而不是行对数据进行分组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接