【问题标题】:Creation of mxArray *without* memory allocation/initialization创建 mxArray *无*内存分配/初始化
【发布时间】:2013-12-27 15:16:20
【问题描述】:

我经常通过在 mex 中实现一些 matlab 例程来优化它们。 到目前为止这工作正常 - 但每当创建返回 mxArray 时,它会在我使用 mxCreateNumericArray 构建它时被预初始化。
在我的大部分工作中,我不需要预先分配(归零)内存。太伤心了——我找不到匹配的命令(分配内存而不归零)。

所以我的问题可以通过两种方式来回答:

  1. 我必须调用哪个命令来创建 mxArray 而不将内容归零?
  2. 如何在不为Pr(和Pi)字段分配内存的情况下构建mxArray,稍后我将通过mxMalloc 分配内存。

一个想法是构建大小为 (0,0) 的数组 - 但这是最​​终的解决方案吗?

【问题讨论】:

标签: matlab memory-management initialization mex


【解决方案1】:

我想,构建一个大小为 (0,0) 的矩阵与一种“空”构造函数一样接近。 之后,您必须使用 mxMallocmxRealloc 调整数组大小。

我怀疑这会带来显着的性能提升,除非您正在处理非常大的数组。

【讨论】:

  • 嗨,这听起来很清楚。我尝试使用 mxCreateNumericArray 创建一个 12345 x 12345 数组,通过 timeit 生成 5.7992 秒,而不是使用 0,0 创建并使用 mxMalloc 和 mxSetDimensions 处理相同的数据和大小,导致 5.8946 秒。这很奇怪,不是吗? (在这段时间内也完成了一些解压缩,两次调用完全相同。)
  • 这有点奇怪,是的。多次测试运行的时间是否可比?如果是这样,看来matlab做得很好......
  • 我用最后几个小时测试了不同的方法。结合你在这里的台词,我想我可以自己回答我的问题——因此我很快就会在这里发布我的结果作为答案。谢谢
  • 这里提出的建议听起来很明智,但根据我的经验并没有提供任何好处。我不知道为什么,但我的猜测是 mxMalloc 也会通过缓存拖动所有分配的内存。
【解决方案2】:

塞巴斯蒂安的那些台词让我玩了起来。我认为,以下几行显示了我的问题的答案。
用文字表示 - 即使将空间归零,结果也很快。
在我当前的应用程序中,我测试了四种不同的场景:

  1. plhs[0] = mxCreateNumericArray(targetDimCount, targetDims, targetClass, mxREAL);
  2. plhs[0] = mxCreateNumericArray(0, 0, targetClass, mxREAL); mxSetData(plhs[0],mxMalloc(destLen_in_Bytes));
  3. plhs[0] = mxCreateNumericArray(0, 0, targetClass, mxREAL); mxSetData(plhs[0],mxRealloc(mxGetData(plhs[0]),destLen_in_Bytes));
  4. plhs[0] = mxCreateUninitNumericArray(targetDimCount, targetDims, targetClass, mxREAL);

导致这些时间(对于第一列中给出的大小分配的矩阵)

 size       time 1       time 2       time 3       time 4

 1000     0.037401     0.037263     0.039294     0.037628
 2000     0.14906      0.14937      0.15278      0.14917
 3000     0.33497      0.33449      0.34601      0.33749
 4000     0.61207      0.60546      0.61563      0.60086
 5000     0.94057      0.93076      0.96147      0.95723
 6000     1.3497       1.3475       1.3794       1.3559
 7000     1.837        1.8265       1.8776       1.846
 8000     2.398        2.3893       2.4625       2.3885
 9000     3.0264       3.047        3.1374       3.0339
10000     3.7658       3.7677       3.8392       3.7862
20000    15.208       14.968       15.404       15.143
30000    13.583       13.58        13.955       13.648
50000    13.291       13.236       13.535       13.478

从这些数字来看,我的观点是,重新分配是一个坏主意(但还不错,正如时间所显示的那样),将值归零并不是一个很大的努力。好的——人们可以进一步怀疑 10000 到 30000 之间的行为——但这会更科学。使用 malloc(仅用于测试目的)不起作用,因为分配的存储需要用于 plhs - 除非存储由 mx*** 分配,否则它会崩溃

【讨论】:

  • 我自己尝试过解决同样的问题,但没有找到干净的解决方案。值得看到使用 malloc() 而不是 mxMalloc() 的时间(不是你应该在实践中这样做),因为时间表明 mxMalloc 正在通过缓存拖动所有分配的内存(因为代码随着分配而变慢尺寸增加)。
  • 也可以尝试使用 mxSetPr 而不是 mxSetData 看看是否有什么不同。
  • @user664303 - 我找不到使用 mxSetPr 的区别 - 从文档中它只使用类型化指针而不是 void 指针。
  • 看看 James Tursa 在文件交换上的 uninit 实用程序:mathworks.com/matlabcentral/fileexchange/…
【解决方案3】:

对我们来说,另一个可能的选择可能是未记录的函数mxFastZeros。这是众多undocumented mex functions 之一。您可以在this Matlab Central answer 中了解它的用途。我很想知道它是否与创建一个零大小的矩阵有什么不同。

【讨论】:

    猜你喜欢
    • 2018-02-18
    • 2012-12-04
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    相关资源
    最近更新 更多