【问题标题】:Matlab in-place operation A = A + (B*C)Matlab 就地操作 A = A + (B*C)
【发布时间】:2014-05-28 09:28:40
【问题描述】:

当对以下测试进行内存分析时,感兴趣的行上只有一个(相对)小的分配(可能是缓冲结果以添加完整的列),因此我认为这是一个就地操作,其中每个结果组件的乘法直接加到目的矩阵A的对应元素上。

A = rand(4000);
B = rand(4000,40);
C = rand(40,4000);

A = A + (B*C); % Line of interest

eigs(A,1) % to ensure the computation of A is actually done

然而,在更复杂的情况下(例如在一个循环中,前面有额外的操作),这行代码创建了一个完整的临时(大小为 A)

B*C

我想知道为什么会这样。在大规模设置中,这可能决定 Matlab 是否出现内存不足。可能是我高估了 JIT,它甚至没有在测试用例中进行就地操作;或者如我所愿,也有一些技巧可以推动 JIT 就地处理更复杂的代码。

编辑

简单的测试用例:

复杂的测试用例:

(如果你想知道,这里:R = N = 29008)

复杂代码:

尽管有内存分析器输出,我可以在 htop 中看到,在第 244 行期间,内存使用量激增了 W 的大小,约为 6GB。

htop 在第 244 行:

第 244 行之后的htop

【问题讨论】:

  • 您提到了两种不同的情况,能否请您显示重现这两种情况的代码片段?关于人们如何看到临时矩阵已创建(或未创建)的提示也可能有所帮助。
  • 作为一种可能的可视化:分析器窗口的屏幕截图。
  • 这会带来一个问题,因为 Matlab 内存分析器没有为复杂代码提供有用的信息;不过我还是会发截图

标签: matlab octave vectorization jit in-place


【解决方案1】:

简单地使用TaskManager (我正在使用Windows 7),无论有没有for 循环,我都会得到B*C 大小的内存峰值:

function [] = toto()
%[
    A = rand(6000);
    B = rand(6000);
    C = rand(6000);

    pause(10);
    %for k = 1:10,
        A = A + (B*C); % Line of interest
    %end
    pause(10);

    eigs(A,1) % to ensure the computation of A is actually done
%]

您确定使用htop 进行的内存分析足够准确还是测试相关?

【讨论】:

  • 两者都不是。考虑到您的测试将表明简单案例的内存分析器输出已经是错误的。在这种情况下,我会接受这个操作不是就地完成的。
  • 这难道没有某种意义吗?您创建了一个副本,您可以在第二个操作中使用它吗?
  • @litro 您可以使用feature('accel', 'off') 暂时关闭优化以确保。看到这个link
  • 我的问题的目的不是对 JIT 功能进行逆向工程尝试,而是从 知道 A = A + (B*C) 是否可以就地完成的人那里得到答案与否。
猜你喜欢
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 2012-07-26
  • 2011-08-01
  • 1970-01-01
  • 2021-10-04
相关资源
最近更新 更多