【问题标题】:How to access multiple elements of an array efficienty in C++?如何在 C++ 中有效地访问数组的多个元素?
【发布时间】:2016-04-07 17:37:32
【问题描述】:

如果我是第一次发帖,我希望我能达到标准...

出于效率的原因,我正在将一个最初用 MATLAB 编写的程序翻译成 c++(我对此很陌生)。我实际上正在处理的一段代码在一个步骤中恢复了对向量(矩阵)的各种索引的访问。例如,如果 M1 是一个大小为 10x15 的矩阵,程序将定义一个新的矩阵,如下所示:

idxs1 = [1 2 3];
idxs2 = [1 2 3 4 5];
M2 = M1 (idxs1 , idxs2);

将 M2 生成为大小为 3x5 的矩阵。现在,我猜MATLAB实际上所做的就是逐个访问由索引给出的M1的各个位置,然后通过重新排列获取的许多内容来构造M2,这一切都非常有效。

我的问题是,如何在 c++ 中重现这种机制?据我所知,没有直接的方法可以连续访问数组的各种索引,而且我使用的for 循环似乎相当麻烦。也许有一些聪明的方法可以做到这一点而不需要“太多”的处理器时间?另外,出于教育目的,如果有人可以解释执行此类操作时 MATLAB 实际执行的操作,我将不胜感激。

提前致谢,给您带来的不便深表歉意!

P.S:以防万一它增加了问题,我正在使用 MEX 文件来链接两种语言。 P.S2:顺便说一句,我发现了一些相关的问题,但与其他语言有关:

【问题讨论】:

  • 你将很难提高 Matlab 的效率。
  • 您为什么认为在效率方面击败 Matlab 会很容易? Matlab主要使用BLASLAPACK进行矩阵运算。这些库最初是用 fortran 编写的。您可以通过使用一些c wrappers 来使用这些功能。 Matlab 还使用称为 mxArray 的矩阵类型。我想可以使用其他矩阵库,但除非你是一个无聊的数学天才,否则你应该避免自己写。
  • C++ 矩阵库与non-contiguous submatrix views。还有一个 MEX 界面
  • 非常感谢您提供的有用答案。我错误地表达了自己,暗示我试图击败 MATLAB =) 我实际上正在做的是翻译成 C++ 以便之后跳转到 CUDA。也就是说,事实证明我的程序实际上比 MATLAB 运行得更快,但前提是系统的大小“足够小”,MATLAB 在更大的系统(即矩阵)上击败了我的实现,而且,占用的数量大致相同时间不管大小。这是我希望通过犰狳复制的智能编码(不是我)的成就。感谢您的回答! =)

标签: c++ arrays matlab matrix matrix-indexing


【解决方案1】:

“Armadillo 是一个高质量的 C++ 线性代数库,旨在在速度和易用性之间取得良好的平衡

适用于直接在 C++ 中进行算法开发,或将研究代码快速转换为生产环境;语法(API)故意类似于 Matlab”

链接:http://arma.sourceforge.net/

【讨论】:

  • 正是我想要的。现在,让它与 MEX 文件一起工作并不是小菜一碟……非常感谢!
  • @AlejoAlberti 很高兴听到!如果您对答案感到满意,请接受并继续前进
【解决方案2】:

数学程序的数据结构可能是最复杂的。我什至无法弄清楚您示例的第 3 行实际上做了什么,所以我什至无法猜测 MATLAB 是如何实现任何东西的。

我可以告诉你的是,一行 MATLAB 几乎可以肯定隐藏了大量的操作。如果你想重新创建它,你只需要使用几个 for 循环来创建一个实用函数,这些循环一个接一个地复制所有正确的索引。最终,这与一个 MATLAB 并没有太大的不同。

如果您需要支持大量的矩阵运算并且您正在处理一个大型项目,那么您可能想要寻找一个 C++ 矩阵库。我没有推荐的,但 Boost 是一个流行的 C++ 库,用于许多用途,包括矩阵。 (也可以自己制作数据结构,但不建议新手使用。)

【讨论】:

  • 很好的建议,而且暂时写一个数据结构肯定是我的能力范围之外的。实际上,“C++ 矩阵库”是@Severin、patrik 和 hbrerkere 的建议,所以我认为你们的目标都是相同的。尽管我还没有进入 Boost 文档,但我认为我会选择 Armadillo,因为它与 MATLAB 的语法相似(以及速度问题 -stackoverflow.com/questions/14414906/…,尽管比较没有非常彻底地执行)。感谢回复!
【解决方案3】:

MATLAB 究竟做了什么未指定,并且根据索引的不同可能会因情况而异,即使对于给定的一组索引,它也可能因机器而异。所以我们不要猜测。

特别是,未指定 MATLAB 是否物理复制 M1。这样的副本可以伪造,从而节省时间。该技术被称为“写时复制”。

在 C++ 中,这也是可能的,但更难。此外,现有的容器类都不支持它。

如果要复制元素,CPU 不会成为瓶颈。相反,内存总线会限制你。当索引不连续时尤其如此。对于 3x5 矩阵,时间将由开销决定 - 连续性并不重要。

【讨论】:

  • 感谢您的回答,完全同意“不投机”的前提。只是想可能有一些我忽略的标准调整。我的程序需要一步一步(避免显式的for)矩阵的一部分,不一定要复制它(类似于“指向许多内存空间的指针” - 这显然不存在 - 会做)。关于巴士的好建议!好消息是索引是连续的。矩阵的大小约为 150000 x 100,所以最好不要复制,对吧? =)
猜你喜欢
  • 2022-07-15
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
  • 1970-01-01
  • 2016-10-01
  • 2021-05-20
  • 2014-06-07
  • 2012-11-11
相关资源
最近更新 更多