1、提高Matlab仿真程序执行性能正文结构背景与意义影响仿真程序性能的因素提高仿真程序性能的建议执行速度测试方法背景与意义Matlab与其他语言的差异:n例如对于C或者C+来说,只要算法的思想不变、采用的数据结构相同,不同人写出来的语句在效率上一般不会产生太大的差别。所以,对于C来说,程序的好坏一般由算法来决定。n但是,在Matlab中,同样的算法、同样的结构、同样的流程,如果采用的语句不一样,在效率上就会大大不同。n所以,了解有关Matlab执行效率的内容,对我们的接下来的仿真实践会有很多帮助。影响仿真程序性能的因素l很多书上都说Matlab是解释性语言,执行效率不如C/C+高。这曾令我对Ma
2、tlab的执行速度失去信心;l然而这句话虽然是正确的,却非常不全面,导致我们将速度慢的原因归咎于工具语言本身;l实际上,Matlab通过借助混合编程的方法,其执行效率与编译型语言之间的差别已经不是很明显;l大多数情况下,执行效率的低下,是由于我们忽视了一些影响仿真程序性能的因素导致的影响仿真程序性能的因素For-循环函数调用内存分配矩阵索引其它影响仿真程序性能的因素For循环传统观点认为for-loop是影响性能的致命环节,让我们来对此验证:lticltocElapsed time is 0.000001 seconds.lticlfor i=1:1000000lendlTocElapsed
3、time is 0.003144 seconds.影响仿真程序性能的因素For循环从上面的实验结果可以得出以下结论:ntic/toc语句的时间开销可以忽略不计nfor-loop语句本身的时间开销也非常小,关键的影响效率的地方不在于循环本身,而是在于循环的内部接下来我们就借助for循环,分析一下其他的各个影响效率的因素影响仿真程序性能的因素函数调用函数的分类:build-in functionMEX-function(MATLAB executable)m-functionanonymous functioninline function其它相关内容(不讲):function handlefev
4、al影响仿真程序性能的因素内建函数lticlfor i=1:1000000l cos(0);lendltocMean elapsed time is 0.032866 seconds.影响仿真程序性能的因素m-函数lticlfor i=1:1000000l func(i);lendltocMean elapsed time is 0.185556 seconds.lfunction func()lend影响仿真程序性能的因素匿名函数lticlfor i=1:1000000l funca(i);lendltocMean elapsed time is 0.561228 seconds.lfunc
5、a=(x);影响仿真程序性能的因素内联函数lticlfor i=1:1000000l funci(i);lendltocMean elapsed time is 19.5606 seconds.lfunci=inline(,x);影响仿真程序性能的因素函数调用影响仿真程序性能的因素函数调用从上面的实验结果可以得出以下结论:n内联函数的调用时间开销最小,约为for-loop本身的10倍nm-函数的调用时间开销约为内联函数的6倍,约为for-loop本身的60倍n匿名函数的调用时间开销约为m-函数的3倍,约为for-loop本身的187倍n内联函数的调用时间开销过大,尽量不要在循环中使用n另外ME
6、X-函数的调用时间开销,理应介于内联函数和m-函数之间影响仿真程序性能的因素矩阵索引lticlA=zeros(1000000,1);lfor i=1:1000000l A(i)=i;lendltocMean elapsed time is 0.007592 seconds.影响仿真程序性能的因素矩阵索引lticlA=zeros(1000000,1);lfor i=1:1000000l A(i,1)=i;lendltocMean elapsed time is 0.007954 seconds.影响仿真程序性能的因素矩阵索引lticlA=zeros(1000000,1);lfor i=1:100
7、0000l A(i:i,1)=i;lendltocMean elapsed time is 0.663598 seconds.影响仿真程序性能的因素矩阵索引lticlA=zeros(1000000,1);lfor i=1:1000000l A(i,:)=i;lendltocMean elapsed time is 0.273345 seconds.影响仿真程序性能的因素矩阵索引lticlA=zeros(1000000,1);lfor i=1:1000000l A(i,1:1)=i;lendltocMean elapsed time is 0.730042 seconds.影响仿真程序性能的因素
8、矩阵索引lticlA=zeros(1000000,1);lfor i=1:1000000l A(i:i,1:1)=i;lendltocMean elapsed time is 1.00852 seconds.影响仿真程序性能的因素矩阵索引影响仿真程序性能的因素内存分配lticlA=zeros(1000000,1);lfor i=1:1000000l A(i)=i;lendltocMean elapsed time is 0.009025 seconds.影响仿真程序性能的因素内存分配lticl%A=zeros(1000000,1);lfor i=1:1000000l A(i)=i;lendlt
9、ocMean elapsed time 20 minutes.影响仿真程序性能的因素内存分配l因此,如果不预先分配好内存,将会大大增加仿真时间,拖慢执行效率;l所幸的是,由于这个现象的重要性,Matlab的编辑器能够发现并提示这个问题,会用红的波浪线标记出来影响仿真程序性能的因素其它关于Matlab还有很多细节及技巧,可以通过在程序中查询产品帮助,获得设计师的建议,一点一点积累下面列举一些编程的建议提高仿真程序性能的建议向量化函数化预分配内存随时用测试工具检测执行效率提高仿真程序性能的建议向量化lN=0:0.1:1000;lfor i=0:10000l y(i)=cos(N(i);lend向量
10、化:lN=0:0.1:1000;ly=cos(N);提高仿真程序性能的建议向量化lY=arrayfun(function,X);向量化函数:laccumarraylarrayfunlbsxfunlcellfunlspfunlstructfun提高仿真程序性能的建议函数化尽量使用内建函数,内建函数的速度是最快的m-函数的执行效率也很高MEX-函数的执行效率仅次于内建函数,将耗时的代码写成MEX-函数,将大大提高运行速度匿名函数,内联函数,以及一些面向对象方法,尽量不要在执行次数多的循环体内使用提高仿真程序性能的建议预分配内存A=zeros(1000,1);A=int8(zeros(100,1);
11、A=zeros(1000,1,int8);常用的预分配内存函数:zerosoneseye执行速度测试方法tic/toc语句profile函数profiler工具执行速度测试方法tic/toc语句tic/toc语句,前面已经介绍了实例。tic/toc不一定要成对出现,一个tic后面可以有多个toc,但需要需要重新计时的时候,要再次执行tictoc的结果可以用变量接收下来,如T=tocT(k)=toc;执行速度测试方法profile函数proscript-namepropropro 对于单个m文件,你只需要简单的在Matlab 命令行窗口(Command Window)输入pro,然后是m文件名,
12、比如文件名为calculation.m的文件,直接输入calculation,执行完毕以后,输入pro,就可以观察每条语句的耗时。结束后别忘了pro。还可以使用pro清除之前执行的结果。执行速度测试方法profile函数运行到断点pro单步执行propropro 对于在一大堆语句中单独调用的m文件,如果你仅仅需要用matlab观察这个函数的耗时,那么用断点运行到你需要查看的函数之前,然后按照上面仿真单个文件的方法,在命令行窗口执行pro,然后调用函数,接下来用pro查看报告,最后输入pro结束。执行速度测试方法profiler工具执行速度测试方法profiler工具执行速度测试方法profil
13、er工具执行速度测试方法profiler工具执行速度测试方法profiler工具附:减少内存使用的建议为变量定义合适的数据类型x=zeros(1,1000,uint8);当使用大的矩阵变量时,预先指定维数并分配好内存,避免每次临时扩充维数重用变量,避免生成大的中间变量,并删除不再需要的临时变量当程序需要生成大量数据时,可以考虑定期将变量写到磁盘,然后清除这些变量。当需要这些变量时,再重新从磁盘加载当矩阵中数据极少时,将全矩阵转换为稀疏矩阵clear,save,load,whos,pack附:for-loop中的循环变量lfor i=1:1000l ilendlfor i=1:0.1:1000l ilend附:for-loop中的循环变量lfor i=2 7 11;l ilendi=2i=7i=11附:for-loop中的循环变量lN=2 7 11;lfor i=Nl ilendi=2i=7i=11附:for-loop中的循环变量lN=2 7 11;1 5 13;lfor i=Nl ilendi=2 1i=7 5i=11 13