【问题标题】:Why is reshape so fast? (Spoiler: Copy-on-Write)为什么reshape这么快? (剧透:写时复制)
【发布时间】:2016-07-03 22:05:35
【问题描述】:

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

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)

【问题讨论】:

    标签: performance matlab matrix octave vectorization


    【解决方案1】:

    表现良好的说明

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

    现在来看reshape 的特殊情况。这里看起来 A 和 B 不一样,但在内存中它们是一样的。保存数据的底层数组不受reshape 操作的影响,无需移动任何内容:all(A(:)==B(:))。调用 reshape 时 MATLAB 所要做的就是创建一个新引用并使用矩阵的新维度对其进行注释。 重塑矩阵只不过是创建对输入数据的新引用,该引用带有新维度的注释。 reshape 的运行时间小于 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 运行时间比reshape 慢得多,在 1µs 和 1ms 之间。可能是因为一些恒定的计算开销。内存消耗几乎为零,运行时间与输入大小无关。没有此注解的操作的运行时间低于 1µs,大致相当于 reshape

    2 OCTAVE 中的零成本

    写这篇文章时最初使用的是 MATLAB 2013b。使用 MATLAB 2019b 确认数字。

    【讨论】:

    • 您好,非常好的答案!左右索引是MATLAB/OCTAVE最强大的功能之一,为什么“贵”?花费超过必要的时间? [我不是指像B(1:numel(A)) = A 这样的整个数据副本,正如你所解释的那样,B=A(或变体)可能会花费零时间。] 那么我该如何降低B(1:lenx:end, j) = A(i, 1:leny:end).' 的成本?你知道(很多)更快的方法吗?
    猜你喜欢
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 2013-08-04
    • 2020-03-22
    • 2014-06-26
    • 2017-08-28
    • 2022-01-14
    • 2018-03-22
    相关资源
    最近更新 更多