我在具有 24GB RAM 的机器上运行了这两个示例profile('-memory','on');
。此分析器选项将显示在每一行代码上分配和释放的内存。这些应该是总额而不是净额。我检查了一个简单的函数,它有 net 0 free 和 alloc,它报告了总金额。但是,似乎没有 .m 代码支持的内置命令不会向分析器提供细粒度的内存报告。
我对以下代码进行了几次测试:
% truncTest.m
N = 628000000;
M = 364000000;
clear Z
Z = zeros(N,1,'single');
Z(M:end) = [];
Z(1) % just because
clear Z
Z = zeros(N,1,'single');
Z = Z(1:M);
Z(1)
N
对于它们的价值,内存分析结果M
是:
好吧,就分配和释放的内存而言,这两行看起来都是一样的。也许这不是全部真相。
所以,出于好奇,我减少M
到200
(只有 200 个!)没有改变N
,做了profile clear
并重新运行。分析声明:
有趣的是,Z=Z(1:M);
现在几乎是瞬时Z(M:end)=[];
的,而且速度更快。正如预期的那样,两者都释放了大约 2.4GB 的内存。
最后,如果我们去另一个方向并设置M=600000000;
:
现在 evenZ=Z(1:M);
很慢,但大约是Z(M:end)=[];
.
这表明:
Z=Z(1:M);
只需抓取指定的元素,将它们存储在新缓冲区或临时变量中,释放旧缓冲区并将新的/临时的分配给数组Z
。我能够使我较弱的 4GB 机器从 2.45 秒变为 5 分钟,只需增加 M
并保持N
不变。M/N
对于 small ,可能在所有情况下都绝对更喜欢这个选项。
Z(M:end)=[];
总是重写缓冲区,并且执行时间也随之增加M
。实际上总是较慢,并且似乎呈指数增长,不像Z=Z(1:M);
.
- 内存分析不会提供有关这些内置操作的细粒度信息,不应被误解为在命令执行时释放和分配的内存总量,而是净变化。
更新 1:只是为了好玩,我将测试计时在以下值范围内M
:
显然比分析提供更多信息。这两种方法都不是无操作,但Z=Z(1:M);
速度最快,但它可以使用几乎两倍于Z
for M/N
near 1 的内存。
更新 2:
R2008b 之前的 32 位 Windows 中提供了一个相对未知的feature
称为mtic
(and )。mtoc
我仍然将它安装在一台机器上,所以我决定看看这是否能提供更多洞察力,因为我知道(a)从那时起发生了很大变化,(b)它是 32 位 MATLAB 中使用的完全不同的内存管理器。尽管如此,我还是将测试大小减小到N=128000000; M=101000000;
并进行了查看。首先,feature mtic
对于Z=Z(1:M-1);
>> tic; feature mtic; Z=Z(1:M-1); feature mtoc, toc
ans =
TotalAllocated: 808011592
TotalFreed: 916009628
LargestAllocated: 403999996
NumAllocs: 86
NumFrees: 77
Peak: 808002024
Elapsed time is 0.951283 seconds.
清理,重新创建Z
,另一种方式:
>> tic; feature mtic; Z(M:end) = []; feature mtoc, toc
ans =
TotalAllocated: 1428019588
TotalFreed: 1536018372
LargestAllocated: 512000000
NumAllocs: 164
NumFrees: 157
Peak: 1320001404
Elapsed time is 4.533953 seconds.
在每个度量(TotalAllocated
、TotalFreed
、NumAllocs
等)中,Z(M:end) = [];
效率都低于Z=Z(1:M-1);
。我希望可以通过检查这些数字中的这些值来辨别内存中发生了什么N
和M
,但我们会猜测旧的 MATLAB