本帖最后由 厚积薄发 于 2010-1-25 22:54 编辑
3 r+ ` F g0 B0 Z5 k8 ^* U o6 Z" p
加速matlab运行的三重境界 加速matlab运行的三重境界
, u* ^5 Y' O8 J; a%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0 l& j# n# W$ m4 ^, W%%%%%%%%%%%%%%%%%%%%%%%2 Y8 W7 l& D6 D8 C% B2 c
一、 遵守Performance Acceleration的规则
8 e4 M, s& G6 W9 [! v! X二、 遵守三条规则 v# e1 C, R9 u0 j/ P& I3 y
三、 绝招 u/ N( _) o7 @5 B0 Z; w+ W
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%, R8 e& L6 N+ r
%%%%%%%%%%%%%%%%%%%%%%% 一、 遵守Performance Acceleration的规则
" u# g7 a" |8 h3 N关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
% V9 P2 _2 n! g" a# T其规则总结如下7条:/ I% x6 Q: r, p: ]8 ~
1、只有使用以下数据类型,matlab才会对其加速:, g+ F5 b- [5 d# K1 ~9 R7 X7 H
logical,char,int8,uint8,int16,uint16,int32,uint32,double! `* ^) P; g/ A2 X: Y/ L+ B
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
6 {, x; }" i' ~! s2 ~& k/ are,single,) z2 ~2 r# f6 Q! u! ]+ V/ ~
function handle,java classes,user classes,int64,uint645 ?4 i" h3 ~1 d2 o) t7 @" r$ }
2、matlab不会对超过三维的数组进行加速。0 }& J, t% L6 _0 ~+ q
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 a# m- {: p7 S n8 `* S7 A
来表示;2 z0 R1 P* O- z, Y6 e
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数' I, W/ q- \+ g7 N
据类型,只使用
1 b- F, r# B$ h; I `" b' b三维以下的数组;c、循环内只调用了内建函数(build-in function)。
+ A8 q( M. F% j4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将" E6 c6 H5 c! G6 @$ L% k
加速运行。
6 u& \* v4 i& O1 _/ s7 v/ {5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
, G* l5 H% A* X: H4 O. ax = a.name; for k=1:10000, sin(A(k)), end;, j. r/ w4 L8 P4 z- y
6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速- x' l% c. {4 X- f1 {
度。8 `- i4 r- L- }) E. U* \
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低+ {" m& |7 t2 Q
运行速度。( [" X& s" Q" Z, z5 K
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%: p/ V7 W4 N# @, y
%%%%%%%%%%%%%%%%%%%%%%%1 P7 Z. x- d2 s" c- T; H6 E8 L2 s+ ^
二、 遵守三条规则& S- z4 A" E$ M# E5 e+ r' Y: T2 a! s& B
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic, e* @( l4 v% I& S+ r) E
h means it is designed: h }+ ^6 A F' w) u. `
for vector and matrix operations. You can often speed up your M-file c
$ g, _4 D% Q/ aode by using
0 a! }7 m" P6 ~7 s+ {vectorizing algorithms that take advantage of this design. Vectorizati3 d# @- F' @+ B o/ X
on means converting
5 Z5 c+ S5 \9 _# Y+ _( yfor and while loops to equivalent vector or matrix operations.”。改进, c b6 h6 i0 D0 w) ?1 n- y1 ~
这样的状况有两种方法:& O: n+ L0 ^$ a! N6 a7 H" {3 G
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
) ]; {0 n. z* a. ~3 I3 Q, \i=0;$ g- Z( Q2 J/ i: x
for t = 0:.01:103 u& r9 T6 g4 s1 k. n2 _
i = i+1;, p' e% T9 O7 f$ R) R1 S
y(i) = sin(t);" n% r: P8 b8 {" T- v
end
. X" ~* Z7 z, g$ \$ p3 j. y7 O替换为:
. Z# @- P( c* [% @2 }" c# @; c: B, Ct = 0:.01:10;3 \. m. t6 |3 A& M" n
y = sin(t);8 ?6 } O- l% u7 J
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i5 |7 O+ U( ?% s5 L8 o- n
permute、permute、) f' A# D9 |, m$ T9 \* t4 R
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums) ]) C) C# W6 H" v/ B% t/ Y
um、ind2sub、
& ^ w5 E+ a! _ndgrid、repmat、sort、sum 等。4 V" G9 ?1 Z/ e: J% Q8 k
请注意matlan文档中还有这样一句补充:“Before taking the time to
6 @8 X2 E, A! M9 B6 ?$ X! B( nvectorize your code, read the section on Performance Acceleration.
- Y* ^3 T% @8 X: bYou may be able to
+ O) O s5 T, g$ F9 l# Z, M) p9 i# n3 Uspeed up your program by just as much using the MATLAB JIT Accelera
; W$ s9 C' e" V9 w6 ftor instead of3 Z0 p# ?7 V# E8 E$ I9 B
vectorizing.”。何去何从,自己把握。
+ Z b% _. D! S" Hb、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
# {7 G9 ]* F( o) r: N4 q: d8 o行循环次数少的,
5 M2 _8 Q$ X! {; A7 j3 N内环执行循环次数多的。这样可以显著提高速度。" @# m% Y$ n5 p( s! c. j. x1 S" M
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
9 A# r( T) H1 X: ges、cell、struct、
" M |# G: d, B3 S* P- ^repmat等。
; U" R0 C _& q- `% g' Sb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
, e+ U, }4 a& ~& }A = int8(zeros(100)); G" V. z7 V/ N+ c. M- P' n
换成:
. h% u- H7 i4 \0 u% b5 Y8 W& {A = repmat(int8(0), 100, 100);( `( V# q/ g' Z" C3 l+ f
c、当需要扩充一个变量的大小、维数时使用repmat函数。
' ~+ g( G. z F2 o8 M9 l) B. U$ O& ~3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
5 |3 \& i3 I( C( y8 E7 ]! _b、使用Functions而不是Scripts 。1 {* O; G F- I" B/ D" |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
U/ w; ]) \: `( }%%%%%%%%%%%%%%%%%%%%%%%0 h8 `' t1 J. h
三、 绝招
% D: O" G5 Y" [你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
; f6 a7 W- d4 {/ `8 ~1、改用更有效的算法8 \# x! f' q6 q
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
" t `1 a# {) [3 m# Y% G# B% k
2 e0 T k4 C9 A" _8 d 来源:iLoveMatlab' y6 Z4 J0 C8 C* y+ b, o
+ p7 M* B0 f/ d: J1 M( u
0 w# w" k9 b" Q1 @9 G, j
在这里本人推荐使用‘绝招’。 |