QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1171|回复: 1
打印 上一主题 下一主题

Matlab中的一些小技巧 *(每日一资料)*(二)

[复制链接]
字体大小: 正常 放大

3503

主题

538

听众

5990

积分

  • TA的每日心情
    开心
    2017-2-7 15:12
  • 签到天数: 691 天

    [LV.9]以坛为家II

    社区QQ达人 元老勋章 发帖功臣 新人进步奖 优秀斑竹奖 金点子奖 原创写作奖 最具活力勋章 助人为乐奖 风雨历程奖

    群组2013年国赛赛前培训

    群组2014年地区赛数学建模

    群组数学中国第二期SAS培训

    群组物联网工程师考试

    群组2013年美赛优秀论文解

    跳转到指定楼层
    1#
    发表于 2016-7-2 09:42 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta

    MATLAB内存管理

    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启动 (在快捷方式属性里面的 "..../matlab.exe" 改为("...../matlab.exe" - 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 命令,随时减少不必要的内存。

    因此,治本的方法如下:

    1. 在命令行输入 pack 整理内存空间

    当内存被分为很多碎片以后,其实本身可能有很大的空间,只是没有作构的连续空间即大的Block而已。如果此时Out of Memory,此时使用pack命令可以很好的解决此问题。

    2. 使用稀疏矩阵或将矩阵转化成稀疏形式 sparse

    如果矩阵中有大量的0,最好存储成稀疏形式。稀疏形式的矩阵使用内存更少,执行时间更短。例如:

    000×1000的矩阵X,它2/3的元素为0,使用两种存储方法的比较:

    Name

    Size

    Bytes

    Class

    X

    1000x1000

    8000000

    double array

    Y

    1000x1000

    4004000

    double array (sparse)

    3. 尽量避免产生大的瞬时变量,把没必要的变量clear掉或当它们不用的时候应该及时clear

    4. 减少变量,尽量的重复使用变量(跟不用的clear掉一个意思)。

    5. 把有用的变量先save,后clear 掉,需要时再读出来。

    下面介绍一下关于clearsaveload的特殊用法,这对在forwhile等多重循环里出现out of memory非常有效。

    for k = 1:N    % N为循环次数

    % ---------------------

        var0 = k; % 获得变量var0   


    %----------------------

        string = [sprintf('var_%d', k) ' = var0;' ];

        eval(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_ ”开头的变量

    还有很多关于saveclearload等用法,具体help一下。

    6. 使用单精度 single 短整数替代双精度 double

    Matlab 默认的数字类型是双精度浮点数 (double),每个双浮点数占用 8 个字节。对于一些整数操作来说,使用双浮点数显得很浪费。在Matlab 中可以在预先分配数组时指定使用的数字类型如以下命令:zero(10, 10, uint8) 。对于浮点数,在很多精度要求不高的情况下,可以使用4个字节的单浮点数 (single),可以减少一半的内存。关于单、双浮点数的精度对照如下,以便根据需要选择使用:

    single: 精度 (1.1921e-007) 最大数 (3.4028e+038)

    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;

    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不能使用abclear的空间,因为它们均小于2.1 MB,而同时它们也很可能是不连续的。最好的方法:

    c = rand(2.1e6,1);

    clear

    a = rand(1e6,1);

    b = rand(1e6,1);

    使用16.4 MB RAM

    9. 如果可行的话,将一个大的矩阵划分为几个小的矩阵,这样每一次使用的内存减少。                     





    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    zxcqwe123        

    0

    主题

    12

    听众

    46

    积分

    升级  43.16%

  • TA的每日心情
    奋斗
    2016-8-20 10:17
  • 签到天数: 18 天

    [LV.4]偶尔看看III

    社区QQ达人

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2025-5-7 14:52 , Processed in 0.590747 second(s), 60 queries .

    回顶部