数学建模社区-数学中国

标题: 加速matlab运行的三重境界 [打印本页]

作者: zzwszj    时间: 2004-12-21 11:00
标题: 加速matlab运行的三重境界

发信人: fork (撒哈拉沙漠的沙), 信区: Matlab+ U s4 I% L: m2 u4 ^ 标 题: 加速matlab运行的三重境界 . ]) I1 z. m* Q4 \ X发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)5 Z( s5 ~1 ?2 c2 ^0 P; Y) s # q/ b3 ]6 T9 Y3 k加速matlab运行的三重境界

1 s4 U, L; }% I9 B% s : C# d' Y! q/ }, D4 t

一、 遵守Performance Acceleration的规则 + [5 M' H# L, l3 n 1 k1 r" V, n9 b* P; e关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将6 ]1 d& e; N: j, ` 其规则总结如下7条:* n& H# o4 Q' e' I 1、只有使用以下数据类型,matlab才会对其加速:$ ^/ A$ O' v5 d2 O' |0 V' S) r$ c logical,char,int8,uint8,int16,uint16,int32,uint32,double& z/ W" x; g; Z+ f5 v 而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu8 q9 b- y% g$ b& z re,single, % i5 l- @/ |7 q0 \4 M) s$ d9 }8 ~% |# { function handle,java classes,user classes,int64,uint641 a! P8 n6 Q; a6 L 2、matlab不会对超过三维的数组进行加速。' d: m' W: g! `& z, r6 e 3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 # o$ I/ K/ X5 \来表示; 6 O: i I6 ?* ~ W2 T# Ab、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数 8 j u& i7 D+ ?+ f1 `1 A: O! _据类型,只使用* R* C# x1 M M4 Z0 x& T 三维以下的数组;c、循环内只调用了内建函数(build-in function)。+ E" g' B+ n; W 4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将 1 V- t3 O. Y2 G7 j7 J: A加速运行。 7 ] Z6 L% ^5 s6 J& t2 d5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句: l3 V6 i q1 I$ M x = a.name; for k=1:10000, sin(A(k)), end;; |' A6 O+ H2 |+ e* c 6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速6 {6 ~/ ?. r, }' k% Z 度。4 i/ T* \ `2 }' h- Y 7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低# }# Y1 Y4 a3 @. i! m! R 运行速度。 0 V+ Q7 ]8 n! {% _

4 z! }. Z" L6 W& V

二、 遵守三条规则 6 X+ I9 c0 N5 N6 o# i# p # O- \ {9 G* ~5 k5 L1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic& O+ ]7 m" }" T$ ?* I h means it is designed 3 d. C4 t3 y0 U5 Q5 ~" e: T5 t5 }) k1 ?: B7 X. u+ y# ?- } for vector and matrix operations. You can often speed up your M-file c. F, [9 e. D# N) j4 k3 _: }4 l ode by using7 g. s; `7 X4 j8 ?6 K( B- L vectorizing algorithms that take advantage of this design. Vectorizati 6 C/ \/ t$ ~" R% F( Won means converting2 v' E. r S, Y5 f for and while loops to equivalent vector or matrix operations.”。改进 ! D1 n4 y4 K) \ m3 O, x5 p这样的状况有两种方法: / c( @5 l5 W" a# M# L9 \1 _" u+ F4 r% t# B0 k7 W/ I a、尽量用向量化的运算来代替循环操作。如将下面的程序: 7 U7 F; q8 T, F( {+ c5 z, L$ q4 S) D) ?& v5 V) s( n i=0;6 @' N" M3 x1 L9 _ |. Z for t = 0:.01:10 6 W4 C' c3 K, t' q+ U6 a4 Bi = i+1; # Z* w0 z* I7 d/ o: f7 Iy(i) = sin(t);: T: n- e3 [: C9 V4 i end . @5 N* d8 M) b3 r# f% {1 }替换为: 9 L) K0 x! r4 } a! P; {t = 0:.01:10;+ L6 }: c2 A1 i/ U W5 e9 k y = sin(t); _9 K3 {9 O; Z- q! j- s5 w8 ?2 v速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i 4 v1 T+ x& r$ K2 V. r0 s& S; j' upermute、permute、; [/ Y6 g5 g& ]" V reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums 1 F. c! N1 B P6 ?um、ind2sub、, F2 x8 j( [1 e! @ ndgrid、repmat、sort、sum 等。 4 g( o+ v3 h7 \, ^- N" F$ q" E, u& j( |& X. p5 @) u 请注意matlan文档中还有这样一句补充:“Before taking the time to " Z5 D2 A1 e$ j4 m! k/ [! k 9 C, ^) k% Q+ \/ Y9 e4 Q. Pvectorize your code, read the section on Performance Acceleration.5 ]; c. X) L2 x# t4 v9 N8 N You may be able to9 ]6 ^! M2 y; w; _$ {: H4 \( y- u speed up your program by just as much using the MATLAB JIT Accelera / j7 |7 o/ e7 w V( D9 s: ^tor instead of; n2 a$ {( Z! O vectorizing.”。何去何从,自己把握。 8 w* v. d9 _/ k2 j 1 A: w9 d$ J% [; t: |8 D, ~, ^b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执 ; n1 H2 U# H& e! I7 O5 X( t行循环次数少的,( V" e2 d2 y4 Q6 ~7 y0 e2 J1 N; ` 内环执行循环次数多的。这样可以显著提高速度。 8 n6 ^ x$ D6 D- y5 H 9 p# I, c! p/ H7 X" c2 h1 V) w0 G2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on # a, h$ s+ w t* i; u8 B" C% |9 H+ ges、cell、struct、 ( T Q( P- y) M# F# xrepmat等。+ w1 m \- @0 Z b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:4 ]" Z7 @5 Q! q6 l( v7 D# t 0 x: y$ M9 I% e8 ?8 S, C A = int8(zeros(100));5 S2 d4 A8 {# s2 x2 Z 换成: . @7 S$ i7 G7 s3 |5 A$ D8 y2 LA = repmat(int8(0), 100, 100); 6 |: n4 d1 \0 q: ^c、当需要扩充一个变量的大小、维数时使用repmat函数。& t1 N1 d) ~( |( H1 x2 ` 0 m" C& k& j; c, d5 O3 }) |, t3 S$ s 3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。 9 B& F9 s3 c; b% _, M. b rb、使用Functions而不是Scripts 。7 @, _0 h# J! }3 s

7 Y- C4 R }$ p, W) N

三、 绝招4 L! o4 H3 O) ? 9 K* l5 ^0 o" `你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。 * V! Y! ~! q X* O0 h: G+ X1、改用更有效的算法 ; N9 C' J. x( G! W! W2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。 ; y. ~* ]0 X( {* s) ]3 J: o/ n. N5 J! j 关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++6 M8 f9 A/ ~: e3 ?6 H1 M 语言文件,VC编译”。


作者: fup    时间: 2004-12-21 16:00
Great.
作者: ornewuser    时间: 2004-12-22 11:47
好文章
作者: zzwszj    时间: 2004-12-22 13:01

注意

( P- t* M) |/ M3 @/ f0 J

加速之前应该先测试9 G, y8 U9 Z1 o! x/ } 使用profiler可以获得程序各个部分的耗时 2 G1 ]7 X; v/ f( J7 d如此就能高效的加速 1 n8 k, `3 h1 E& H$ k

# W7 y6 \0 _6 j7 F/ {6 K) F

因为有的时候导致速度变慢的原因是逻辑结构不合理,* V1 [& N! n5 n$ R4 X, e) u! p7 ` 而不涉及程序技术

# l9 @4 u( H& l, R* j


作者: hamburger_2004    时间: 2004-12-22 21:10
收到![em02]
作者: hamburger_2004    时间: 2004-12-22 21:12
多谢掌门人,对俺的帮助太大了。
作者: 布赖    时间: 2005-1-4 18:13
有没有经过考验的????????




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5