如何提高MATLAB运行效率

上传人:cl****1 文档编号:556627083 上传时间:2024-03-15 格式:DOC 页数:9 大小:60.50KB
返回 下载 相关 举报
如何提高MATLAB运行效率_第1页
第1页 / 共9页
如何提高MATLAB运行效率_第2页
第2页 / 共9页
如何提高MATLAB运行效率_第3页
第3页 / 共9页
如何提高MATLAB运行效率_第4页
第4页 / 共9页
如何提高MATLAB运行效率_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《如何提高MATLAB运行效率》由会员分享,可在线阅读,更多相关《如何提高MATLAB运行效率(9页珍藏版)》请在金锄头文库上搜索。

1、如何提高MATLAB运行效率(1)在我们的领域,MATLAB是进行实验的最主要的工具之一。我听到过很多抱怨说MATLAB很慢,可是这往往不是MATLAB的问题,而是因为自己程序没有写好。MATLAB是我非常欣赏的一种语言,堪称灵活易用和高效运算的结合典范。 作为解释语言,MATLAB进行高效运算的秘诀有几个方面: (1) JIT即时编译技术。Matlab在第一次加载运行一个函数的时候,会在后台对它进行某种程度的编译和优化,使得后续运行更快。因此,除了第一次运行需要进行语句解释之外,后面运行的其实是已经放在内存中的经过优化的中间码。所以,很多时候我们可能会看到第一次运行一个新函数,比它后面几次的

2、运行明显慢一些。不过目前的JIT技术还不是非常成熟,和标准的编译语言相比还有相当差距,仅凭这个MATLAB还不能称为高效。 (2) 向量化(Vectorization)。这是MATLAB最著名的特色。向量化配合经过高度优化的数值运算引擎,是其高效运算的最重要的基石很多MATLAB的使用者都明白这一点。能够转化成矩阵操作的规则运算过程,使用MATLAB计算远比自己手工用C/C+实现高效。我自己做过很多次对比profile,MATLAB在关键的核心运算上的实现可以比自己用C/C+按照标准的routine进行实现快几十倍。 其实这不完全是MATLAB的功劳,其实MATLAB是建基于BLAS和LAPA

3、CK等的基础数学运算包的基础上的。Intel和AMD都发布了这些东西的vendor-implementation,并且针对各自的CPU进行了大量的优化,这非个人之力所能企及。因此,我从来都强烈不建议个人用C/C+去实现数值运算的关键代码(学习数值分析课者除外)。 不过,对于向量化这个事情,也不宜极端化,下面的一些例子说明在哪些时候,for-loop比vectorization更适合: (a) 粗粒度的算法流程控制。比如,你要实现一个迭代算法,循环做一个事情直到收敛。只要循环几次或者几十次,但是每个循环内部要进行大量的复杂运算,那么你就没有必要费心把这层循环给vectorize掉了。除非收敛结果

4、有某种close-form的解析解。 (b) 如果向量化可能导致产生巨型矩阵,则使用前要三思!很多情况下,向量化是一种用空间换时间的行为,就是通过把数据组织成某种方式,从而使得内建的高效引擎能得以应用。但是,有些时候要处理大量的数据,可能导致其组织过程需要耗费额外的数百兆乃至千兆内存空间,那么这有可能造成效率的不升反降。原因有几个方面:第一,数据组织过程也是需要时间的,最起码它也需要大量的操作进行密集的内存读写和用于定位的偏移量计算。这方面增加的时间 vs. 向量化节省的运算时间,孰轻孰重,需要衡量。第二,分配额外的大块内存是一件非常耗时的事情,它可能导致虚拟内存的使用,那么当对这块矩阵进行读

5、写和计算时可能涉及频繁的内存与外存交换区的I/O,这回造成效率的严重下降。我一直不赞同在Out of Memory的情况下,通过增大虚存来解决问题,这样,即使你勉强让程序能继续运行下去,运行时间也会变得极为缓慢这时应该做的是对程序进行重新思考和设计,降低其对内存的耗用。第三,vectorization有些时候还可能增加实际运算次数,这往往出现在不适合的向量化过程中。这样,即使你通过生搬硬套的向量化过程让操作变成矩阵运算,但是增加的无用计算使得即使是更高效的引擎也无法挽回你的损失了。说了这么些,不是想劝说从向量化的道路退回去,而是提醒在做一些事情的时候,要考虑得周全一些。 (3) Inplace

6、 Operation。这是一个很有趣的事情,MATLAB的对象管理策略是Copy-on-Write,就是说你把一个矩阵传给一个函数的时候,会先传引用,而不产生副本,而当函数要对这个矩阵修改的时候,才会制造出它的副本出来,让函数去修改。这样听上去很完美,既保护了输入矩阵不被改变,又避免了大量无谓的复制。不过,这个策略真的没有缺陷么?可以看看下面的例子 A = rand(2000, 2000);for i = 1 : 1000 A = f(A);endfunction A = f(A)A(1) = A(1) + 1; % a temporary copy of A is produced for

7、modificationreturn; % the modified temporary copy is assigned to A 在上面的代码中,只是想对A的第一个元素做1000次加法,结果却导致了对整个有四百万元素的大矩阵做了1000次副本复制!而且这些副本其实没有用,只要f(A)直接对A的原矩阵进行修改,这些巨大的浪费就能避免。你可能跟我argue说,这里完全可以写成A(1) = A(1) + 1000,不用这么搞。我想说明的是,我只是想举一个简单例子说明,Copy-on-write的策略为什么可能造成巨大的效率浪费。其实,很多小修改没法像上面那么容易合并。 以前,为了解决这个问题,f

8、函数的作者需要自己写一个mex function来避开MATLAB的保护机制,直接改写A。后来matlab自己也意识到这种策略在实际中的问题,于是他们改写了解释器,采用了一种办法:A = f(A, .) 当它发现这样的定义和调用的时候,它会很智能地了解到你其实是想改写A这个输入,于是它就把操作改成inplace,直接对A进行,避免拷贝。这种修改的策略,在2006b后才比较正式的运用,在旧版Matlab中仍旧不同程度地存在上述问题。我在2007a中,测试了两种f的写法: function y = f0(x) y = x + 1; end function x = f1(x) x = x + 1;

9、 end确实发现大量调用f1比f0快了好多倍。所以,如果确实是想改变input的话,函数定义中要让input parameter和output parameter同名,以触发这种智能的解释机制。并且建议升级到最新的2007a版本,这个版本在这方面进行了重要改善让MATLAB更快(2)MATLAB是一门在数值运算方面非常高效的语言,对于提高MATLAB的效率,有一些大家熟知的方法,比如避免使用for循环,向量化,使用C-mex写核心,等等。这些原则大体是没错的,但是教条地运用有时反而会降低效率。 根据问题的规模,适当选择向量化的策略 向量化的基本思想是以空间换时间,通过把要处理的对象转化成一个矩

10、阵,集中处理。这比起非向量化的处理方式往往需要消耗更多的内存。在内存紧张的时候,内存分配的开销可能是很大的。 比如,给定一个列向量v1,和一个行向量v2, 计算矩阵M,使得M(i, j) = v1(i) + v2(j)。一种常用的向量化实现:m = length(v1); n = length(v2);M = repmat(v1, 1, n) + repmat(v2, m, 1);这个过程中,除了M以外,还要创建两个大小为m x n的临时矩阵。repmat创建临时矩阵有一定的overhead,主要花费在元素索引上。由于元素加法的向量化收益本身并不显著,扣除repmat的额外开销后,得益就更小了

11、。另外,当这些矩阵很大,接近物理内存容纳能力的时候,必然导致和虚拟内存进行频繁的交换,耗费大量的IO时间,向量化可能得不偿失。这种情况下,下面这种向量化程度略低的方式可能是更好的选择: M = zeros(m, n);if m 0);ns = ns(ns 0);sp = 1, cumsum(ns(1:end-1) + 1;result = vs(cumsum(sp);对于图像处理或者二维信号问题,善用filter。 比如,要对每个像素,基于其局部邻域进行一些计算。即使整个计算本身不是线性的,但是只要能分解成线性局部运算的组合,就可以利用filter。 比如,对于图像I, 产生V,使得V(i, j)是像素I(i, j)周围w x w邻域的像素的方差。I = im2double(I);h = ones(w, w) / (w * w);M = imfilter(I, h, symmetric);M2 = imfilter(I.2, h, symmetric);V = M2 - M.2;再谈MATLAB效率(3)关于MATLAB的效率问题,很多文章,包括我之前写的一些,主要集中在使用向量化以及相关的问题上。但是,最近我在实验时对代码进行profile的过程中,发现在新版本的MATLAB下,for-loop已经得到了极大优化,而效率的瓶颈更多是在函数调用和索引访问的过程中。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 大杂烩/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号