有些时候,我们需要分析Matlab程序运行过程中所占用的最大内存。如果只是得到程序运行到当前位置所占用的内存,可以简单在程序当前位置插入memory命令即可:
user = memory;
MemUsed_now = user.MemUsedMATLAB;
但如果我们想要的是整个程序在运行过程中占用内存的最大值,即峰值内存,而且我们的程序又包含了很多子函数,再使用上述命令就有些不方便了。该怎么办呢?
这时可以使用profile on –memory命令。
举个例子,程序包含三个函数,分别是matrix_gen.m, matrix_mul.m和matrix_eig.m:
function [ randn_matrix ] = matrix_gen(size_matrix)
randn_matrix = randn(size_matrix);
end
function [ randn_matrix ] = matrix_mul(randn_matrix)
randn_matrix = randn_matrix'*randn_matrix;
end
function [ V,D ] = matrix_eig(randn_matrix)
[V,D] = eig(randn_matrix);
end
我们在主程序test_demo.m里依次调用上面三个函数:
rdn_mtx = matrix_gen(10000);
mul_mtx = matrix_mul(rdn_mtx);
[V, D] = matrix_eig(mul_mtx);
测试主程序运行过程中所占用的峰值内存。完整的主程序test_demo.m如下:
clear;close all;clc;
profile on -memory
tic
rdn_mtx = matrix_gen(10000);
mul_mtx = matrix_mul(rdn_mtx);
[V, D] = matrix_eig(mul_mtx);
toc
profile report
p = profile('info');
profile off
fullpath = mfilename('fullpath');
%[path, name, ~] = fileparts(fullpath);
fullname = [fullpath, '.m'];
for i=1:length(p.FunctionTable)
if strcmp(fullname,p.FunctionTable(i).FileName)
idx_file = i;
break;
end
end
PeakMem = p.FunctionTable(idx_file).PeakMem;
TotalTime = p.FunctionTable(idx_file).TotalTime;
disp(['PeakMem = ', num2str(PeakMem)]);
disp(['TotalTime = ', num2str(TotalTime)]);
程序结束后,会弹出如下图所示的程序运行记录:
可以看到,各文件的运行总时间,自用时间(不包含调用子函数的时间),峰值内存等信息。
那么,如何将上述信息自动提取出来呢?总不能运行完一个程序记录一下吧!
上述程序中,profile report命令之后的代码就是完成这个任务的。其中,p = profile('info');是将上述信息存到p中,这是一个结构体:
大部分有用信息都存在字段FunctionTable中。而FunctionTable是一个结构体数组,为了从中读出主程序test_demo.m所占用的峰值内存,首先应该判断主程序的运行信息保存在了第几个位置(一般是第1个,但不一定)。接下来的fullpath = mfilename('fullpath');是得到当前文件的名字(含目录和文件名,但不包含扩展名.m,因此要手动接上),在FunctionTable中字段FileName存储的各函数文件的名字(包含扩展名.m),因此我们用了一个for循环查找主程序的运行信息位于结构体数组FunctionTable中的位置。找到位置后,可以在字段PeakMem中提取出运行占用的峰值内存,单位是字节(Byte),需要转换成MB的话除以两次1024,如果需要转成GB那就再多除以一次1024。如果需要运行时间,也可以在字段TotalTime中得到总的运行时间,可以发现与配合tic和toc得到的时间基本一致。