发信人: fork (撒哈拉沙漠的沙), 信区: Matlab$ N! G- z! a8 V/ Y; `' W: ~9 o! } 标 题: 加速matlab运行的三重境界& Z+ C- L; v8 h# t& Q 发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004) 加速matlab运行的三重境界
z: D; w. n% J$ ]* i2 D+ y: Y一、 遵守Performance Acceleration的规则 & C" @) m) S6 l' s3 m( l& L d, Q 关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将+ x4 {# [7 q' Q8 O' u, c 其规则总结如下7条:( n7 B* h( s2 K9 M 1、只有使用以下数据类型,matlab才会对其加速:( w9 q- k. ~9 i1 X5 H logical,char,int8,uint8,int16,uint16,int32,uint32,double 而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu re,single, ' H# l* s: r. V. g function handle,java classes,user classes,int64,uint64 2、matlab不会对超过三维的数组进行加速。" P4 E5 P1 }! t0 F; o! Q9 r 3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值6 _% S' v/ i2 z3 Z 来表示; b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数7 a u1 c! [" Y( S3 ] 据类型,只使用 三维以下的数组;c、循环内只调用了内建函数(build-in function)。# X0 k/ u2 D% }2 Y- ~( t% } 4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将' _( n! B. {7 r" r 加速运行。 5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:0 R9 u4 d3 Z% U: u x = a.name; for k=1:10000, sin(A(k)), end; 6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速 度。( I. S# Z1 F) G7 i# N 7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低 运行速度。
. f" j+ e! q* ^! ^二、 遵守三条规则 1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic h means it is designed; @! F o. C3 J1 S+ }2 h for vector and matrix operations. You can often speed up your M-file c ode by using vectorizing algorithms that take advantage of this design. Vectorizati on means converting for and while loops to equivalent vector or matrix operations.”。改进 这样的状况有两种方法:) t: i. ^: P/ n$ v2 z! h a、尽量用向量化的运算来代替循环操作。如将下面的程序:0 x) M. k: n* \0 g# p6 ? # |# v/ F7 F* l5 @* A) [ i=0; w! ]8 z/ B; g7 ]$ ^+ s; O6 j0 [ for t = 0:.01:10. V, j8 `& Q+ p& w i = i+1; y(i) = sin(t);: x) A! ?% R& V- z, ?2 b/ V end# J8 ]' N5 J7 g$ j 替换为:: N$ w. E: o3 x- G! ? t = 0:.01:10;# `( F9 X5 X* Q9 k y = sin(t);6 v4 {' J4 S" W k6 }5 n) ^ 速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i permute、permute、8 x8 Z9 o6 G3 w/ z1 x reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums) C. k" Y% q6 h' n) a8 g# K um、ind2sub、0 z _: E. {' V3 i% ]! z8 z ndgrid、repmat、sort、sum 等。) `" s: r& f5 @# Y 请注意matlan文档中还有这样一句补充:“Before taking the time to vectorize your code, read the section on Performance Acceleration.7 t m" o/ A3 y$ q You may be able to speed up your program by just as much using the MATLAB JIT Accelera tor instead of vectorizing.”。何去何从,自己把握。 b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执 行循环次数少的, _4 Z6 H- b7 l- s4 N2 l# L7 v 内环执行循环次数多的。这样可以显著提高速度。 2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on/ J4 {; Q. B1 Y" B es、cell、struct、 repmat等。 b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:2 p! |- w" q3 J y) g: k2 M A = int8(zeros(100)); 换成: A = repmat(int8(0), 100, 100);4 d& Y8 @( ?- [/ v9 I1 y c、当需要扩充一个变量的大小、维数时使用repmat函数。 3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。' S" N! Y& T. F2 l; z1 [3 o b、使用Functions而不是Scripts 。
三、 绝招 - ^, @) m" U2 x2 }, T; t 你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。0 ]+ p1 q& S0 l9 T: w" x$ [ 1、改用更有效的算法 2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。2 D3 {4 D* g1 k3 r % s* s. R7 f( {5 n 关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++, a# a. `6 Y" F. _; I5 r 语言文件,VC编译”。
注意
1 Y9 O# t/ D* i9 a加速之前应该先测试 使用profiler可以获得程序各个部分的耗时% {( o$ Q4 G- T 如此就能高效的加速
1 b# T4 V0 e2 j3 s0 X/ g因为有的时候导致速度变慢的原因是逻辑结构不合理, 而不涉及程序技术
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |