【问题标题】:Out of memory error when using '.*' operation in Matlab在 Matlab 中使用 '.*' 操作时出现内存不足错误
【发布时间】:2017-11-30 21:22:18
【问题描述】:

以下是我在 m.file 中使用的代码:

for idx = i_start:i_end
    CheckTemp = (timeTick > time_tr(idx)) .* (timeTick <= time_tr(idx));
    CheckTemp2 = find(CheckTemp);
    IdxS = min(CheckTemp2);
    IdxE = max(CheckTemp2);
    ......

timeTick 数组是一个大约 100MB 的双数组,idx 大约是从 20004000。因为我一步一步检查m文件,发现循环之前,我的内存提交费用是:817M/5422M。有很多可用空间,对吧?

但是我的 Matlab v6.5 告诉我:Error in '.*', out of memory... 这让我很困惑。

另外,我之前逐行执行了代码。并且没有发生错误。我真的不知道为什么。希望有大神帮忙。。。

如果您需要更多信息,请发表评论。

【问题讨论】:

  • time_tick 是排序数组吗?如果是这样,可能会有更好的实现,它需要更少的内存。
  • time_tr(idx) 是单个标量吗?我很困惑,CheckTemp 不会总是一个零数组,因为 timeTick 不能同时是 > time_tr(idx) 和
  • time_tr 和 timeTick 是否已排序?如果是这样,这可以通过数组单次更有效地完成
  • 没有必要分配 any 与 timeTick 一样大的数组,这是 .*&gt;&lt;= 命令隐式完成的。

标签: matlab out-of-memory


【解决方案1】:

MATLAB memory management page 包含一些有用的信息,例如系统的进程内存限制。一般来说,在运行内存密集型操作之前运行clear all 是个好主意。正如 Daniel 指出的那样,由于 MATLAB 分配数组的能力是基于连续的可用内存,而clear 不保证垃圾回收,因此重新启动 MATLAB 可能是个好主意,尤其是在旧版本上。

顺便说一句,我怀疑你会发现CheckTemp = (timeTick &gt; time_tr(idx)) .* (timeTick &lt;= time_tr(idx)); 总是会给你一个logical 零数组。 .* 在逻辑数组上的作用类似于二进制 &amp;,您可以通过在一种情况下比较 &gt; 和在另一种情况下比较 &lt;= 来保证不会有重叠。也许您打算将time_tr(idx-1) 之类的东西用于其中一个索引?

【讨论】:

  • 是的,谢谢您的旁注...应该是:(timeTick > time_tr(idx)) .* (timeTick
【解决方案2】:

如果对timeTicktimeTr进行排序,可以这样做:

  1. 创建与timeTick 相同大小的额外数组
  2. 单次通过两个数组timeTicktimeTr
  3. 在 Matlab 2015b 中使用以下代码(在我的计算机上)在 150MB 双数组 timeTick 和 2000 个条目数组 timeTr 上大约 0.29 秒。

代码如下(请注意,您必须设置time_tr(end+1) = inf 才能使我的代码正常工作)。

%This code requires last entry of time_tr to be inf, eg. time_tr(end+1)=inf;
n_tick = length(timeTick);
n_tr   = length(time_tr);

IdxS = NaN(n_tr, 1);
IdxE = NaN(n_tr, 1);

i_tick = 1;
i_tr   = 1;

window_start_i_tick = 1; 
window_end    = time_tr(1);

while(i_tick <= n_tick)
   t = timeTick(i_tick);
   if(t > window_end)
      IdxS(i_tr) = window_start_i_tick;
      IdxE(i_tr) = i_tick - 1;

      window_start_i_tick = i_tick;

      i_tr = i_tr + 1;
      while(t > time_tr(i_tr)) %take care of case that we skip past a window/windows
          i_tr = i_tr + 1;
      end

      window_end = time_tr(i_tr);        
   end    
   i_tick = i_tick + 1;
end
IdxS(i_tr) = window_start_i_tick;
IdxE(i_tr) = i_tick;

【讨论】:

    【解决方案3】:

    阅读memory 的文档,您会注意到连续可用的地址空间是限制。您的 Matlab 版本不能使用您的全部内存,它仅限于 32 位地址空间。

    我建议切换到最近的 64 位版本的 matlab 或 octave,它是一个开源克隆。

    【讨论】:

    • 使用相同的windows系统和相同的计算机,我执行上面的代码,它运行良好。所以我真的不认为切换到 64 位会解决问题...
    • 我的意思是逐行执行代码,而不是在 m.file 中......所以这让我感到困惑。
    • Opps,我误会了...对不起,感谢您的评论...但我仍然会尝试找出原因。
    • @Saji 以我的经验,可用的连续地址空间的数量在 Windows 系统上是完全不可预测的。多次运行大多数文件,中间重新启动 Matlab,可能会导致一些成功和一些失败的运行。
    • 你说得对,Daniel...我多次尝试我的代码,一次成功,其他次失败。
    猜你喜欢
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多