【问题标题】:Matlab Horzcat - Out of memoryMatlab Horzcat - 内存不足
【发布时间】:2017-04-26 10:23:00
【问题描述】:

有什么技巧可以避免 matlab 中的内存不足错误? 我假设它出现的原因是因为 matlab 在使用 horzcat 时效率非常低,实际上需要临时复制矩阵。

我有一个矩阵A,大小为108977555 x 25。我想将它与三个向量 d、m 和 y 合并,每个向量的大小为 108977555 x 1。

我的机器有 32GB 内存,上面的矩阵 + 向量占用 18GB。

现在我想运行以下命令:

A = [A(:,1:3), d, m, y, A(:,5:end)];

但这会产生错误:

Error using horzcat
Out of memory. Type HELP MEMORY for your options.

这个合并有什么技巧吗?

【问题讨论】:

    标签: matlab memory


    【解决方案1】:

    使用大型数据集。如果您正在处理大型数据集,则在增加数组大小时需要小心,以避免因内存不足而导致错误。如果您将数组扩展到其原始位置的可用连续内存之外,MATLAB 必须制作该数组的副本并将该副本设置为新值。在此操作期间,内存中有原始数组的两个副本。

    1. 重新启动 matlab,我经常发现它没有完全清理它的内存或者它变得碎片化,导致最大数组大小变小。

    2. 更改您的数据类型(如果可以)。例如。如果您只处理数字0 - 255,请使用uint8,与doubles 的数组相比,内存大小将减少8倍

    3. 从A 开始已经足够大(即108977555x27 而不是108977555x25 并插入到位:

      A(:, 4) = d;
      clear d
      A(:, 5) = m;
      clear m
      A(:, 6) = y;
      
    4. 将数据合并为一种数据类型以减少总内存需求,例如,日期很容易适合uint32。

    5. 让数据分开,首先考虑一下为什么要将数据放在一个矩阵中,是否真的有必要。

    6. 使用C-code 自己进行数据分配(仅当您真的很绝望时)

    延伸阅读:https://nl.mathworks.com/help/matlab/matlab_prog/memory-allocation.html

    【讨论】:

      【解决方案2】:

      即使您可以使用 Gunther 的建议完成它,它也只会占用内存。现在它占用了一半以上的可用内存。那么,那你打算怎么做呢?即使是简单的B = A+1 也不适合。你唯一能做的就是sum之类的东西,或者对部分数组的操作。

      因此,您应该考虑转到 tall arrays 和其他相关的大数据概念,这些概念正是用于处理如此大的数据集。

      https://www.mathworks.com/help/matlab/tall-arrays.html

      【讨论】:

        【解决方案3】:

        你可以先试试mathworks官方网站上提到的高效内存管理策略:https://in.mathworks.com/help/matlab/matlab_prog/strategies-for-efficient-use-of-memory.html

        • 如果您的代码可以使用,请使用 Single(4 字节)或其他一些较小的数据类型,而不是 Double(8 字节)。
        • 如果可能,请使用块处理(如行或列),即将块存储为单独的 mat 文件,并仅加载和访问矩阵中需要的部分。
        • 使用matfile 命令加载大的variables in parts。也许是这样的:

          save('A.mat','A','-v7.3')
          oldMat = matfile('A.mat');
          clear A
          newMat = matfile('Anew.mat','Writeable',true) %Empty matfile
          for i=1:27
          if (i<4), newMat.A(:,i) = oldMat.A(:,i); end
          if (i==4),  newMat.A(:,i) = d; end
          if (i==5),  newMat.A(:,i) = m; end
          if (i==6),  newMat.A(:,i) = y; end
          if (i>6),  newMat.A(:,i) = oldMat.A(:,i-2); end
          end
          

        【讨论】:

          猜你喜欢
          • 2015-05-23
          • 2014-05-20
          • 1970-01-01
          • 1970-01-01
          • 2011-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多