发信人: fork (撒哈拉沙漠的沙), 信区: Matlab 标 题: 加速matlab运行的三重境界 发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004). D5 j4 F7 {" R3 e4 V" t) X, z 加速matlab运行的三重境界
) r, O h: J, _$ T6 E% ^, X一、 遵守Performance Acceleration的规则# `, X7 p2 x9 x8 |/ q: M7 k 关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将7 a( [+ [, z( s: v/ p0 @- _ Y 其规则总结如下7条: 1、只有使用以下数据类型,matlab才会对其加速:5 U% i# N6 ?! T4 H8 }; s logical,char,int8,uint8,int16,uint16,int32,uint32,double 而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu" l; y/ i( ~/ w* S7 D+ Q re,single, f8 {& M4 k5 h% t, g function handle,java classes,user classes,int64,uint64 2、matlab不会对超过三维的数组进行加速。# P+ {- D- L5 M! m$ @2 t, ]7 B. M 3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 来表示;4 S+ t J& B. a0 v8 X b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数/ t7 h0 U+ {) Z1 M8 U" r- u) y 据类型,只使用; J' |' r0 q0 z5 s+ K0 ]$ w" r; a 三维以下的数组;c、循环内只调用了内建函数(build-in function)。 4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将8 ~) a- C) q% l: K- |3 a9 x 加速运行。 5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:$ m1 @5 n& _& c) h* K; l( L) g x = a.name; for k=1:10000, sin(A(k)), end;8 D* H! ?( F! }" P$ M! G 6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速4 U5 h2 S D8 w1 W0 E# l 度。; f/ i6 Q- O- j" _" k/ i3 ^! c, m 7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低6 q& b2 m( s1 `! U7 r 运行速度。2 V2 N2 r$ D: e, E7 V1 z0 I
二、 遵守三条规则* X: z( t$ i6 ?( L d 1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic h means it is designed for vector and matrix operations. You can often speed up your M-file c& M0 d8 ?4 z5 V; |7 E% m, f$ V B1 b ode by using vectorizing algorithms that take advantage of this design. Vectorizati on means converting3 I* X' ~3 G" p6 F9 e$ B* m for and while loops to equivalent vector or matrix operations.”。改进 这样的状况有两种方法:1 j- [7 ~* E% i" t, E9 Q( M( m a、尽量用向量化的运算来代替循环操作。如将下面的程序:0 ~! y5 F/ I" h' p' ^) n* v$ C : m- E3 M# k) o. e q: N' X i=0; for t = 0:.01:10 i = i+1;" p5 [. [# [: ^ _5 q y(i) = sin(t);, L7 s L) f3 c3 G end 替换为: t = 0:.01:10;% l% t0 | S/ i; v6 g9 | y = sin(t);! }" C. \+ e+ l# M/ y( l 速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i permute、permute、 reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums8 b5 _: H Z8 V) w# {' q! P um、ind2sub、 ndgrid、repmat、sort、sum 等。 请注意matlan文档中还有这样一句补充:“Before taking the time to vectorize your code, read the section on Performance Acceleration. You may be able to7 S/ H- x: G Q0 i speed up your program by just as much using the MATLAB JIT Accelera4 E$ n) Q- N* F$ r/ f! J tor instead of vectorizing.”。何去何从,自己把握。/ \; b/ Y' ~# h- \+ G : j3 M# j/ k g; H# ~4 H" b b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执 行循环次数少的, 内环执行循环次数多的。这样可以显著提高速度。4 _: l, g- j% V& d' ` : ]9 m9 u0 U! j 2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on& v3 |; D% l. q5 F+ L' }4 _" ^& f6 x es、cell、struct、1 H( c/ E1 f( }" ~) j* Y m repmat等。. ]4 E" Q1 B& H7 X b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:9 h( b$ [5 R) W6 | A = int8(zeros(100));$ K9 _4 Q. r+ t! F* `! s 换成:: }6 t4 Q; G& s- [! b$ W A = repmat(int8(0), 100, 100);. M8 g1 p1 Q3 f( N8 M c、当需要扩充一个变量的大小、维数时使用repmat函数。" w( ]' i j) h. p H% s ) j, q/ \% b5 B+ v/ R9 T 3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。 b、使用Functions而不是Scripts 。
7 ^' I, V& @; H. E三、 绝招 # R$ [& C5 [8 P L 你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。$ o; G: l: ^3 l8 r- Q( } 1、改用更有效的算法 2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。) m& v; |9 B1 b W" X6 v/ Z 6 G# z8 G/ V/ B7 @ 关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++ 语言文件,VC编译”。
注意
$ x; c. z2 k' f& p/ ~! P6 F加速之前应该先测试/ q! ]2 \, L) ~ 使用profiler可以获得程序各个部分的耗时# Z/ T1 p) g' z5 _ 如此就能高效的加速. U* R* @" H% G1 d' ~
7 E) b# y- |* X5 I' K ]+ |- }# M' S因为有的时候导致速度变慢的原因是逻辑结构不合理,: `4 w0 {: ^8 {/ P' Z! ] 而不涉及程序技术
0 r& b3 Q7 [* w8 r7 K2 k* N* d, B
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |