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(:)).1B=ipermute(A,p)- 仅适用于的情况all(A(:)==B(:)).1B=squeeze(A) 1shiftdim- 仅适用于以下情况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零成本