1第十一章MATLAB编译器几乎所有使用过MATLAB的科技人员,无不为该软件的简洁、便捷和功能之强大和可靠所震撼,同时也对MATLAB产生了新的期望:一,希望程序能运行得更快;二,希望获得可摆脱MATLAB环境而独立运行的可执行软件。由于MATLAB6.5版采用的编译器(Compiler)已经全面升级,本章内容是在Compiler3.0基础上全部重写的。11.1编译器概述11.1.1编译器的功能11.1.2编译器的性能改进11.1.3编译器的局限性11.1.4把脚本文件改写为函数文件【例11.1.4-1】有一个绘圆的M脚本文件circle.m如下。希望获得一个MEX绘圆程序。(1)[circle.m]clf;r=2;t=0:pi/100:2*pi;x=r*exp(i*t);plot(x,'r*');axis('square')(2)mcc-xcircle???Error:FilecircleisascriptM-fileandcannotbecompiledwiththecurrentCompiler.Errorin==D:\MATLAB6P5\toolbox\compiler\mcc.dll(3)[circle_f.m]:functioncircle_f(r)clf;t=0:pi/100:2*pi;x=r*exp(i*t);plot(x,'r*');axis('square')(4)mcc-xcircle_f(5)circle_f(0.5)whichcircle_fd:\mywork\circle_f.dll2-0.5-0.4-0.3-0.2-0.100.10.20.30.40.5-0.5-0.4-0.3-0.2-0.100.10.20.30.40.5图11.1-111.2编译器的安装和配置11.2.1配置MATLAB编译器的前提准备(1)(2)11.2.2为产生MEX文件进行预配置11.2.2.1对MATLAB编译器应用程序mex的设置11.2.2.2配置正确性的验证(1)cdd:\myworkmexmy_yprime.cmy_yprime(1,1:4)whichmy_yprimeans=2.00008.96854.0000-1.0947d:\mywork\my_yprime.dll(2)mcc-xmy_yprime_m%1my_yprime_m(1,1:4)whichmy_yprime_mans=2.00008.96854.0000-1.0947d:\mywork\my_yprime_m.dll(3)3图11.2-211.2.3为产生独立外部应用程序进行预配置11.2.3.1对MATLAB编译器mbuild应用程序的设置11.2.3.2配置正确性的验证(1)cdd:\myworkmbuildmy_ex1.c图11.2-3(2)mcc-pmy_hello.m%1图11.2-4(3)4图11.2-511.3MATLAB编译器使用入门11.3.1由M文件创建CMEX文件的入门算例【例11.3.1-1】先编写M文件,然后生成相应的MEX文件。该文件用以判断方阵是否奇异。cdd:\mywork(1)[exm1.m]functiony=exm1(A)[m,n]=size(A);ifm~=n;error('Aninputmatrixshouldben-by-n.')endr=rank(A);ifr==mdisp('Thismatrixisnonsigular')elsedisp('Thismatrixissigular')end(2)(3)mcc-xexm1(4)A=[1,0,1;2,1,0;4,1,4]exm1(A)whichexm1A=101210414Thismatrixisnonsigulard:\mywork\exm1.dll511.3.2由M文件创建外部应用程序的入门算例【例11.3.2-1】建立一个脱离MATLAB环境,可独立运行的外部程序。该程序的功能是:对于给定矩阵A,如果存在S使得S-1AS=Λ,则要求出一个S,否则给出信息说明所给的矩阵A不能对角化。(1)[exm2.m]functionexm2A=[4,0,0;0,3,1;0,1,3];S=exm2_f(A)[exm2_f.m]functionS=exm2_f(A)[m,n]=size(A);ifm~=nerror('输入矩阵应是方阵!');end;e=eig(A);%same=0;fori=1:m-1forj=(i+1):mife(j)==e(i)same=1;endendend%ifany(any((A'-A)))&(same==1)error('矩阵无法对角化!');end[v,d]=eig(A);S=v;(2)exm2S=001.0000-0.70710.707100.70710.70710(3)mcc-mexm2exm2_f(4)6图11.3-111.4编译指令mcc简介11.4.1mcc的基本调用格式11.4.2mcc的选项标志11.4.2.1编译器(2.2版)选项简介11.4.2.2在命令行中指定选项标志【例11.4.2.2-1】假设当前目录上存在一个文件exm3.m,现要求利用M编译器将它转换为C++语言的源码文件,并要求将原M文件中那注释区的内容作为所得C++源码文件的注释。mcc-t-LCpp-Aannotation:commentsexm311.4.2.3设置缺省选项【例11.4.2.3-1】假设已在WINDOWS\ApplicationData\MathWorks\MATLAB\R13目录下创建了文本文件mccstartup(请注意:该文件不可带扩展名),该文件的内容包括若干编译指令的选项。现要求利用该文件,从exm3.m出发得到C++语言的源文件。cdc:\WINDOWS\Applic~1\MathWorks\MATLAB\R13%typeC:\WINDOWS\Applic~1\MathWorks\MATLAB\R13\mccstartup-t-LC-Aannotation:none!copymccstartuph:\mywork\temp!copyexm3.mh:\mywork\temp!delmccstartup,!delexm3*dirmccstartup%cdd:\myworkdirmccstartupdirexm3*1file(s)copied1file(s)copied7mccstartupnotfound.exm3*notfound.!copyh:\mywork\temp\exm3.md:\myworkmcc-LCppexm3%11file(s)copied???Error:Theoptionsspecifiedwillnotgenerateanyoutputfiles.Pleaseuseoneofthefollowingoptionstogenerateanexecutableoutputfile:-x(generatesaMEX-fileexecutableusingC)-m(generatesastand-aloneexecutableusingC)-p(generatesastand-aloneexecutableusingC++)-S(generatesaSimulinkMEXS-functionusingC)-Bsgl(generatesastand-alonegraphicslibraryexecutableusingC(requirestheSGL))-Bsglcpp(generatesastand-alonegraphicslibraryexecutableusingC++(requirestheSGL))-Bpcode(generatesaMATLABP-codefile)Ortypemcc-?formoreusageinformation.Errorin==D:\MATLAB6P5\toolbox\compiler\mcc.dll!copyh:\mywork\temp\mccstartupC:\WINDOWS\Applic~1\MathWorks\MATLAB\R13mcc-LCppexm3%2direxm3*%3!delmccstartup1file(s)copiedexm3.cppexm3.hppexm3.m11.5编译文件的性能优化11.5.1优化数组【例11.5.1-1】优化标量。假设有以下文件,要求对之编译,比较得到MEX文件的性能。[foo.m]functiony=foo(x)y=2*pi*x;分别运行以下编译指令:mcc-Onone-xfootic;foo(1:10);tocelapsed_time=0.5500mcc-Onone-Ofold_scalar_mxarrays:on-xfootic;foo(1:10);tocelapsed_time=0.1100【例11.5.1-2】而对于非标量的情况,相应的可激活优化选项fold_non_scalar_mxarrays。优化编译以下文件:[test.m]functiony=testy=[10;01]*[pipi/2;-pi-pi/2];8分别运行以下编译指令:mcc-Onone-xtesttic;test;tocelapsed_time=0.8200mcc-Onone-Ofold_non_scalar_mxarrays:on-xtesttic;test;tocelapsed_time=011.5.2优化循环【例11.5.2-1】激活选项array_indexing,可以改善简单的一维或二维数组的索引性能。如果在编译时关闭该选项,编译器将采用通用的索引函数来索引这些简单的数组。[test2.m]functiony=test2(x,i1,i2);y=x(i1,i2);分别运行以下指令:A=magic(4);mcc-Onone-xtest2tic;test2(A,3,4);tocelapsed_time=0.2200mcc-Onone-Ofold_non_scalar_mxarrays:on-xtest2tic;test2(A,3,4);tocelapsed_time=0【例11.5.2-2】激活选项optimize_integer_for_loops,可简化循环。当循环变量的初值和步长均为整数时,编译器将采用C/C++的整型变量,而非MATLAB的数组变量。(建议在调试程序时,不要激活该优化选项。)[test3.m]functiony=test3(x)fori=1:length(x)-1x(i)=x(i)+x(i+1);endy=x;分别运行以下指令,对比各自编译得到的MEX文件的性能:mcc-Onone-xtest3tic;test3(1:100);tocelapsed_time=0.4400mcc-Onone-Ofold_non_scalar_mxarrays:on-xtest3tic;test3(1:100);tocelapsed_time=011.5.3优化条件语句【例11.5.3-1】当条件语句中的两个运算量都是标量整数时,激活选项optimize_conditionals,编译器将优化该条件语句:采用C的条件运算取代原MATLAB的条件运算。MATLAB能够识别出nargin、nargout、for语句的循环变量以及所有整数标量。9[tset4.m]functiontest4(a,b,c,d)if(nargin4)d=0.0;end运行以下指令,对之进行不同的编译,并比较各自得到的MEX文件性能:mcc-Onone-xtest4tic;test4(1,3,4);tocmcc-Onone-Ofold_non_scalar_mxarrays:on-xtest4tic;test4(1,3,4);toc11.6创建独立的外部应用程序11.6.1独立外部程序的工作特点和创建过程11.6.1.