# \; W% G0 n7 |; @/ W. E2 x7 H' _, _加速matlab运行的三重境界/ o3 E, j! P' F
; v9 @3 r0 c# s1 j# w- m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ( ]" L5 a1 ?/ F& r7 e* m%%%%%%%%%%%%%%%%%%%%%%%/ @5 S& M( C7 m5 S
一、 遵守Performance Acceleration的规则 ; C0 @5 j p% q0 T m6 w二、 遵守三条规则7 K' z8 I/ S* m# L5 v* v! v" j
三、 绝招 6 M+ l- @8 {( E5 |, a1 o: g- V6 w+ G+ X: |! ~$ I' Z
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; `6 M* p( C% P! e6 V# T. S% {: T8 F%%%%%%%%%%%%%%%%%%%%%%%' o, \3 H1 _2 G
一、 遵守Performance Acceleration的规则 ; b3 N9 F: U5 ]. P! @8 Q 5 z3 w5 b# W% i1 i1 i关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将 Z2 P! |, }- @1 _; k其规则总结如下7条: 0 Z. {1 J7 v, X' Y Q% B" K1、只有使用以下数据类型,matlab才会对其加速: # F. S* Z @7 H( I1 Blogical,char,int8,uint8,int16,uint16,int32,uint32,double ( H0 s; ?/ B( o1 Z$ r& T! G而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu ; @7 l W. W' }2 a$ S3 {1 tre,single, ! Z5 W) C* k) q0 N2 y9 x8 X; G# V& v5 d# A" l
function handle,java classes,user classes,int64,uint64+ y9 q. w6 |6 `+ u
2、matlab不会对超过三维的数组进行加速。' R. k3 E6 u* p3 E
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 ) Z3 l0 D4 X( J9 h( _5 s4 ~- q来表示;+ O, ?9 f! y/ ]& {
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数* l& p+ k: D- L1 j9 O$ f6 Q# S! A
据类型,只使用 3 m# Q$ `" q" U p, E* N; C( A" d三维以下的数组;c、循环内只调用了内建函数(build-in function)。 . d I! {1 D" e) g2 s3 O4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将 ; H2 |5 A* J* v8 l% H加速运行。' M( G( J3 T: \2 C( ~' G5 Q6 n
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:" d9 u8 \( Q9 g Y- o9 @
x = a.name; for k=1:10000, sin(A(k)), end; + D6 S8 K3 C; Y) e9 |1 `* E' E( [6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速3 t/ Z/ b5 Q& U! V& R+ X, {
度。 ) D. N3 g8 d$ g$ l4 V7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低5 F% j$ ~5 A8 N8 y- V
运行速度。 ( C. S7 V; b, ^5 B; x `/ {3 c " ] f7 u* l0 l' b+ _' ]; s%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* f' _; H7 V. `, Q6 Y7 q: Q% A
%%%%%%%%%%%%%%%%%%%%%%%5 `1 U( a2 v) @' C1 g5 O
二、 遵守三条规则6 H! w5 x* `- I; C
, e; r& Z7 h* g3 j2 B8 q9 B# t1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic! r" J0 u3 M* w
h means it is designed 2 K. \. g) T! w- F0 g5 m1 b8 U" X3 ?( | 2 ]; N7 S6 N8 k% pfor vector and matrix operations. You can often speed up your M-file c 0 D' ]1 X* O3 d. H, F/ r- Z) aode by using& `* \8 K. i5 v5 f- ^# O" F
vectorizing algorithms that take advantage of this design. Vectorizati 8 J8 n( ~: L9 Hon means converting : X; _1 P+ t$ t, p6 Pfor and while loops to equivalent vector or matrix operations.”。改进* o! q1 j( a/ }5 l5 I, Z" H
这样的状况有两种方法:' m/ H/ w/ [& m$ r
4 b2 r8 v8 b: f5 A- N
a、尽量用向量化的运算来代替循环操作。如将下面的程序:- b( J8 C. x5 }, P+ ^/ O
6 P' f+ C( q0 xi=0; + `9 I6 R! @* M a" E) W9 U) Rfor t = 0:.01:10' z' @8 c# }, o& U2 t; z# f Q5 F
i = i+1;! ]( Q. ` O4 L; d) W6 M5 X& R
y(i) = sin(t);7 r9 J& q' F9 P: x9 D
end # i2 v% H* [) a) R8 v& B% R0 |替换为:% c" v; F: _0 {
t = 0:.01:10; 5 f$ A, K. V& Y1 N, M2 s& Ey = sin(t); & ?5 U8 e6 r1 r" h" ] Q速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i, E' \+ A8 L' Y+ [- u
permute、permute、 , `0 s/ u$ I. Y x" e5 F' I& preshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums z3 f# o/ m( k$ V4 kum、ind2sub、5 y2 @5 A% O8 j2 ^/ m3 `
ndgrid、repmat、sort、sum 等。2 ] s! Q/ x$ @' F
, w G( Y# |) G2 v1 N请注意matlan文档中还有这样一句补充:“Before taking the time to" x6 _& S' e5 ?7 W! |
: d: s% } n0 R( Q% q$ W" I+ W1 Uvectorize your code, read the section on Performance Acceleration.6 ]1 [. \9 n/ V B3 g3 p
You may be able to ' S: a- U3 ?; {" y1 x: T# ?speed up your program by just as much using the MATLAB JIT Accelera 9 { }) L E3 wtor instead of . `* V! G; ~3 E, m- t5 w9 ~vectorizing.”。何去何从,自己把握。 ! I7 f( \2 K0 u. E1 a* U $ `4 o- i# T, C1 B* q7 [" ub、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执5 c" `, P6 `" M' q7 u5 j
行循环次数少的, 3 ^0 m& D$ a/ T' ?! @1 X [内环执行循环次数多的。这样可以显著提高速度。 ! B. D3 N$ ~: }; U* r+ j7 c ], h- d4 Y2 e0 q3 E& F6 [, d
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on n3 z. a; n. L: x: Z3 D- d9 z2 hes、cell、struct、5 J1 @3 E" p0 z! x) e, R3 o
repmat等。 2 r0 A, c5 Q0 f! F; fb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:+ L- c: R6 e% S [' c
. `) @$ f; y: z1 l9 R7 W
A = int8(zeros(100));, F0 I- {. I, f. J2 E* V3 A
换成:( z3 q, R+ y+ z: ~
A = repmat(int8(0), 100, 100);1 u! N; [+ u1 N7 |
c、当需要扩充一个变量的大小、维数时使用repmat函数。 # H" }$ D, y; b. z % v7 B* V1 z% @/ t, l3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。 . A o7 T- k5 }- B/ ]$ O Rb、使用Functions而不是Scripts 。 8 }# k# [2 A0 q( ~$ R# D( D' l D" X 2 N8 M$ Q0 ^& `+ I8 o, y6 a/ L) e%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%' [* s7 X4 V$ W- L& j
%%%%%%%%%%%%%%%%%%%%%%% $ w* H& p x3 j7 Y8 f三、 绝招 4 s* U2 o" J& w8 d; U8 f" I6 v( @. _8 y' @5 n) v" {' W: c. D* g
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。 , D! y% c6 X; ], n3 _) P6 l1、改用更有效的算法% J2 z* u& T" k1 ]; X
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。6 ]. g4 Z+ j {+ `7 l
. B3 `3 s u+ w4 x( N' A& k* O
关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++ ' S1 R' I( E( f7 }# V语言文件,VC编译