Matlab内存管理调优优化问题(转载)
感谢原⽂博主,因⽆法转载,所以直接copy过来了:
以下为正⽂:人教版七年级英语上册
⽤ Matlab 进⾏⼤规模科学计算或仿真时,内存是⼀个需要时常注意的问题。在matlab⾥运⾏
>>system_dependent memstats
就可以看到内存的使⽤状况。当你写的 Matlab 程序跳出“Out of Memory” 时,以下⼏点措施是需要优先考虑的解决⽅法:
1. 升级内存
2. 升级64位系统
3. 增加虚拟内存
4. 采⽤3GB开关启动系统
由于32位 Windows 操作系统的限制,每个进程只能使⽤最多 2GB 的虚拟内存地址空间,因此 Matlab 的可分配内存也受到相应的限制。Matlab 7.0.1 引进了新的内存管理机制,可以利⽤ Windows 的 3GB 开关,使⽤ 3GB 开关启动的 Windows 每个进程可以在多分配 1 GB 的虚拟地址空间。具体做法是:修改C盘根⽬录 boot.ini 启动选项加上 /3G,例如:
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect /3G
5. 如果必有必要,不要启动java虚拟机,采⽤matlab -nojvm启动 (在快捷⽅式属性⾥⾯的 "..../") 改为("...../" -nojvm)
6. 关闭Matlab Server
7. Windows中字体、窗⼝等都是要占⽤系统资源的,所以在Matlab运⾏时尽量不要打开不⽤的窗⼝。
除此以外,更关键的是需要弄清楚以下⼏个问题:
问题⼀:Matlab是如何存储矩阵的?
Matlab中矩阵是以Block,也就是块的形式存储的。也就是说,当Matlab在为即将存储的矩阵划分块时,如果没有相应⼤⼩的连续内存,即使实际内存没有被完全使⽤,它还是会报告“Out of Memory”。
问题⼆:如何⾼效使⽤Memory?
Matlab 中数组必须占⽤连续分配的内存段,当⽆法为新建的数组分配连续的内存段的时候,”Out of Memory” 就会出现。在使⽤的过程中,由于存储单元的不断的被分配和清除,反复分配和释放数组会使内存被分割成不连续的区域,可⽤的连续内存段减少,很容易造
成“Out of Memory”。因此当 Matlab 刚刚启动时其连续内存最多,此时往往可以新建⾮常⼤的数组,这⼀点可以⽤命令
feature(’memstats’)(在 7.0 版本以上)看出。如果现实的最⼤连续内存段很⼩,但实际可⽤内存(⾮连续的)仍旧很多,则表明内存中碎⽚太多了。此时可以考虑⽤ pack 命令,pack 命令的作⽤就是将所有内存中的数组写⼊硬盘,然后重新建⽴这些数组,以减少内存碎⽚。此外,在命令⾏或者程序中都可以使⽤ clear 命令,随时减少不必要的内存。
因此,治本的⽅法如下:
bigbear
1. 在命令⾏输⼊ pack 整理内存空间
当内存被分为很多碎⽚以后,其实本⾝可能有很⼤的空间,只是没有作构的连续空间即⼤的Block⽽已。如果此时Out of Memory,此时使⽤pack命令可以很好的解决此问题。
2. 使⽤稀疏矩阵或将矩阵转化成稀疏形式 spar
如果矩阵中有⼤量的0,最好存储成稀疏形式。稀疏形式的矩阵使⽤内存更少,执⾏时间更短。例如:
focus是什么意思如果矩阵中有⼤量的0,最好存储成稀疏形式。稀疏形式的矩阵使⽤内存更少,执⾏时间更短。例如:
below的反义词
000×1000的矩阵X,它2/3的元素为0,使⽤两种存储⽅法的⽐较:
Name
Size
Bytes
Class
X
bitlocker是什么
1000x1000
8000000
double array
Y
1000x1000
4004000
baidoudouble array (spar)
3. 尽量避免产⽣⼤的瞬时变量,把没必要的变量clear掉或当它们不⽤的时候应该及时clear。
4. 减少变量,尽量的重复使⽤变量(跟不⽤的clear掉⼀个意思)。
5. 把有⽤的变量先save,后clear 掉,需要时再读出来。
下⾯介绍⼀下关于clear、save、load的特殊⽤法,这对在for或while等多重循环⾥出现out of memory⾮常有效。
bottomlinefor k = 1:N % N为循环次数
% ---------------------
var0 = k; % 获得变量var0
%----------------------
string = [sprintf('var_%d', k) ' = var0;' ];
eval_r(string); % 等价于 var_k = var0;
save(sprintf('var_%d.mat', k), sprintf('var_%d')); % 等价于 save var_k.mat var_k
clear(sprintf('var_%d')); % 等价于 clear var_k
end
如果要读取刚才存取的变量var_k, (k = 1,2, ..., N). 那么,可以使⽤如下⽤法:
for k = 1:N
load(sprintf('var_%d.mat', k)); % 等价于 load var_k.mat k = 1,2, ..., N
end
另外,还有⼀些⾮常有⽤的⽤法。如果⽤清除刚才读取的变量 var_k, k = 1, 2, ..., N
clear '-regexp' '^var_' % 清除所有以“ var_ ”开头的变量
还有很多关于save、clear、load等⽤法,具体help⼀下。
6. 使⽤单精度 single 短整数替代双精度 double
gate是什么意思Matlab 默认的数字类型是双精度浮点数 (double),每个双浮点数占⽤ 8 个字节。对于⼀些整数操作来说,使⽤双浮点数显得很浪费。在Matlab 中可以在预先分配数组时指定使⽤的数字类型如以下命令:zero(10, 10, ‘uint8′) 。对于浮点数,在很多精度要求不⾼的情况下,可以使⽤4个字节的单浮点数 (single),可以减少⼀半的内存。关于单、双浮点数的精度对照如下,以便根据需要选择使⽤:single: 精度 (1.1921e-007) 最⼤数 (3.4028e+038)animals maroon 5
double: 精度 (2.2204e-016) 最⼤数 (1.7977e+308)
7. 为矩阵变量预制内存⽽不是动态分配
在动态分配的过程中,由于开始Matlab所⽤的Block随着矩阵的增⼤⽽连续的为此矩阵分配内存,但是由于Block的不连续性,很有可能最开始分配的Block不能满⾜存储的需要,Matlab只好移动此Block以找到更⼤的Block来存储,这样在移动的过程中不但占⽤了⼤量的时间,⽽且很有可能它找不到更⼤的块,导致Out of Memory。⽽当你为矩阵变量预制内存时,Matlab会在计算开始前⼀次性找到最合适的Block,此时就不⽤为变量连续的分配内存。⽐较下⾯两个程序:
for k = 2:1000
x(k) = x(k-1) + 5;river
end
x = zeros(1, 1000);
for k = 2:1000
x(k) = x(k-1) + 5;
end
显然,第⼆个更好最好的⽅法是,在程序⼀开始就位所有⼤的矩阵变量预制存存储单元
8. 尽量早的为⼤的矩阵变量预制内存
Matlab使⽤heap method管理内存。当在Matlab heap中没有⾜够的内存使⽤时,它会向系统请求内存。但是只要内存碎⽚可以存下当前的变量,Matlab会重新使⽤内存。⽐如:
a = rand(1e6,1);
b = rand(1e6,1);
使⽤⼤约15.4 MB RAM
c = rand(2.1e6,1);
使⽤近似16.4 MB RAM
a = rand(1e6,1);
b = rand(1e6,1);
clear
c = rand(2.1e6,1);
使⽤32.4 MB RAM
Matlab不能使⽤a、b被clear的空间,因为它们均⼩于2.1 MB,⽽同时它们也很可能是不连续的。最好的⽅法:
c = rand(2.1e6,1);
clear
a = rand(1e6,1);
b = rand(1e6,1);
使⽤16.4 MB RAM
9. 如果可⾏的话,将⼀个⼤的矩阵划分为⼏个⼩的矩阵,这样每⼀次使⽤的内存减少。