为什么重塑如此之快?

时间:2016-03-17 13:52:37

标签: performance matlab matrix octave vectorization

我有一个大的矩阵A,它是1GB的双倍值,当我将它重塑为不同的尺寸时,它的速度非常快。

A=rand(128,1024,1024);
tic;B=reshape(A,1024,128,1024);toc

Elapsed time is 0.000011 seconds.

怎么这么快?另一个观察结果是,运行该代码并存储两个1GB的矩阵后,MATLAB使用的内存少于应有的内存:Memory used by MATLAB: 1878 MB (1.969e+09 bytes)

1 个答案:

答案 0 :(得分:25)

良好表现的解释

Matlab尽可能使用copy-on-write。如果编写像B=A这样的表达式,MATLAB不会复制A,而是变量AB都是对同一数据结构的引用。只有修改了两个变量中的一个,MATLAB才会创建副本。

现在讨论reshape的特例。这看起来像A和B不一样,但在内存中它们是。保存数据的基础数组不受reshape操作的影响,不需要移动任何内容:all(A(:)==B(:))。调用reshape时,MATLAB必须做的就是创建一个新的引用,并用矩阵的新维度对其进行注释。 重塑矩阵只不过是创建一个对输入数据的新引用,它使用新维度进行注释。重塑的运行时间小于1μs或大致是B=A这两个简单赋值所需的时间。对于所有实际应用,零时间操作。

>> tic;for i=1:1000;B=reshape(A,1024,128,1024);end;toc
Elapsed time is 0.000724 seconds.
>> tic;for i=1:1000;B=A;end;toc
Elapsed time is 0.000307 seconds.

不知道这样的引用到底有多大,但我们可以假设它在几个字节之内。

其他零成本操作

已知具有几乎零成本(运行时和内存)的函数:

  • B=reshape(A,sz)
  • B=A(:)
  • B=A.' - 仅适用于向量
  • B=A' - 仅适用于实数的数字without the attribute complex。请改用.'
  • B=permute(A,p) - 仅适用于all(A(:)==B(:)) 1
  • 的情况
  • B=ipermute(A,p) - 仅适用于all(A(:)==B(:)) 1
  • 的情况
  • B=squeeze(A) 1
  • shiftdim - 仅适用于all(A(:)==B(:))的情况,其中: 1
    • 用于删除前导单例尺寸。
    • 与否定第二输入一起使用
    • 在没有第二个输入参数的情况下使用。

“昂贵”的功能,无论它们是否触及内存中的表示(all(A(:)==B(:))都是真的)

  • 左侧索引:B(1:numel(A))=A; 2
  • (:)以外的右侧索引,包括B=A(1:end);B=A(:,:,:); 2

1 在1μs和1ms之间,运行时间明显慢于reshape。可能是因为一些不断的计算开销。内存消耗几乎为零,运行时独立于输入大小。没有此注释的操作的运行时间低于1μs,大致相当于reshape

2 OCTAVE零成本