为什么重塑如此之快?

Dan*_*iel 15 performance matlab matrix vectorization octave

我有一个大的矩阵A,它是1GB的双倍值,当我将它重塑为不同的尺寸时,它的速度令人难以置信.

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

Elapsed time is 0.000011 seconds.
Run Code Online (Sandbox Code Playgroud)

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

Dan*_*iel 26

解释良好的表现

Matlab 尽可能使用copy-on-write.如果你编写表达式B=A,MATLAB不会复制A,而是两个变量A并且B是对同一数据结构的引用.只有在修改了两个变量之一时,MATLAB才会创建副本.

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

>> 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.
Run Code Online (Sandbox Code Playgroud)

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

其他零成本操作

已知功能几乎为零(运行时和内存):

  • B=reshape(A,sz)
  • B=A(:)
  • B=A.' - 仅适用于矢量
  • B=A'- 仅适用于没有属性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);2之外的右侧索引B=A(:,:,:);

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

2 OCTAVE零成本