本帖最后由 厚积薄发 于 2010-1-25 22:54 编辑
# A- L) `6 _# H7 {: @7 y( x4 P. W2 O. w/ H1 Z. d
加速matlab运行的三重境界 加速matlab运行的三重境界& ~/ h s! x9 j* X- ]5 [
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%' ~0 |( ~/ g3 G( t* o g8 E
%%%%%%%%%%%%%%%%%%%%%%%! _. u0 R4 l8 M& ?8 H- o, s9 K
一、 遵守Performance Acceleration的规则
I8 _0 X: H# X: `2 S二、 遵守三条规则
# ^5 F- W( Z3 p8 l三、 绝招7 c0 B3 d* H+ T4 V9 l
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9 E2 p; z: ~1 t8 p5 U%%%%%%%%%%%%%%%%%%%%%%% 一、 遵守Performance Acceleration的规则
7 J. h2 D4 g& ?$ A+ f关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
% P( X; g4 u3 c其规则总结如下7条:
1 C! u6 u' U: w( {. u1 g1、只有使用以下数据类型,matlab才会对其加速:$ X$ a6 B- ~3 e, c8 ]& b: H* }1 p$ P
logical,char,int8,uint8,int16,uint16,int32,uint32,double( T5 a+ B1 Q- r3 S8 N
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
* K$ i0 ?) y: t: ~ j& H9 ere,single,
# S* @; U: {: b" q$ Q6 \function handle,java classes,user classes,int64,uint648 x9 K7 [$ r% Q8 o1 V* Y' f9 a8 A6 S
2、matlab不会对超过三维的数组进行加速。8 ~6 w, {. q9 K% T6 m& h
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 y; Z: D9 [8 U' U
来表示;
# c4 m/ E4 C- o& A* pb、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
9 e( G& B8 Z7 V1 j. J& v3 n/ ?据类型,只使用' | v0 \! K' ]* q6 H, a, C) R
三维以下的数组;c、循环内只调用了内建函数(build-in function)。/ u J+ |* ^' `5 ]+ @( \$ x) o& R, Y
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将* n& v% i8 z- P, @8 s
加速运行。, G" W7 v8 G6 \2 E
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
# z8 {. ^4 D" X/ Lx = a.name; for k=1:10000, sin(A(k)), end;
+ A- Y7 C6 E! H6 Q p6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
5 K7 Y. e& ]5 i9 Z4 h. v度。% m* t: l+ p/ ~8 Q
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
$ d/ q: J4 ^, F运行速度。
% K6 o6 R* x% k%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9 d7 }$ g- @: p9 Z) d+ u1 n%%%%%%%%%%%%%%%%%%%%%%%$ x& K' o7 z1 \( ]8 L3 M
二、 遵守三条规则* y" j3 T( e8 }! p
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic
, k$ [3 c" A5 F9 k+ @* ~h means it is designed
6 ^2 s. \3 ^. ]5 f/ P3 gfor vector and matrix operations. You can often speed up your M-file c7 L* j) F- d* r5 E! L- q$ V
ode by using' j+ l6 s/ V) C- a0 C( v9 S5 w
vectorizing algorithms that take advantage of this design. Vectorizati& N2 @2 O# D8 `5 ~" S
on means converting
6 }" O, h/ o" E! A' Lfor and while loops to equivalent vector or matrix operations.”。改进
2 }) g f3 Q3 e& v2 U5 b" j这样的状况有两种方法:
# [, K# {( z; v X- s* J8 l( ]a、尽量用向量化的运算来代替循环操作。如将下面的程序:) U# S5 V; _+ [" A
i=0;
1 ]+ Q5 C. j$ Q2 E5 e ^ ]( Q* Vfor t = 0:.01:10
" M6 m4 x3 D2 w) c. xi = i+1;5 q- ?% c9 F$ u( n1 F3 d( q& e
y(i) = sin(t);
9 C" z5 a6 _ }) b2 fend8 `2 i8 E6 K0 n1 s( a: l
替换为:
- f- O4 I8 ]# M. _* nt = 0:.01:10;
: P, \1 a. U" n: n u/ X0 ky = sin(t);
% o* a8 {/ i- f. ?/ ^& s速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i
0 j# y8 n2 |9 O4 I0 Y% ^permute、permute、
: B, w0 C- |) vreshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums; y2 z5 t0 `$ Y$ @8 U
um、ind2sub、. D; [; s5 W/ L. u
ndgrid、repmat、sort、sum 等。! \4 t$ L- M7 B& b3 D
请注意matlan文档中还有这样一句补充:“Before taking the time to
! W% X; \4 d; l/ ~8 P8 ^vectorize your code, read the section on Performance Acceleration.
$ Q6 W; y- s) k6 `7 gYou may be able to
( k: w2 N7 U, d* m# x6 J$ cspeed up your program by just as much using the MATLAB JIT Accelera
' L; m% f, `% H5 n4 C3 |) e/ Rtor instead of, P7 L9 L8 H4 _3 S
vectorizing.”。何去何从,自己把握。
9 J' W& M6 ?1 R! Wb、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执5 a. ? V7 t2 S4 Q! a
行循环次数少的,
* v7 \) @9 N6 o! l内环执行循环次数多的。这样可以显著提高速度。
: U( f1 N" A7 ?) D: H2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
& i' L2 \6 H0 k! ~* \es、cell、struct、
# z8 m4 {9 o9 k6 K* v {repmat等。! `$ K( q4 R" ?
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:' h, C9 V2 R7 Z; Z6 \, @
A = int8(zeros(100));, @3 H, t2 v( e
换成:
1 c% b- b9 F. S$ h3 W$ [$ CA = repmat(int8(0), 100, 100);
! v' s6 X3 k* z8 l- ic、当需要扩充一个变量的大小、维数时使用repmat函数。' E5 D" _% t& b$ K
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。: G) p9 h! C# I5 i
b、使用Functions而不是Scripts 。
/ ~& q' {7 H( I% M! E%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%3 K5 `3 S v; i: D0 r" P, @ f
%%%%%%%%%%%%%%%%%%%%%%%
+ @5 n% m n+ p w三、 绝招
0 H; C1 ?8 p4 k* z l% L" _6 l你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
6 d# y6 u" A6 N% _6 _* C1、改用更有效的算法
) ^0 _1 D% B2 y! f- ?5 v2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。 9 `& ]$ [3 ?7 h) a
1 O7 s% o3 S' U. @, k 来源:iLoveMatlab, h5 `1 w. X& }9 r0 k3 z
a* ~/ M) f* ~! D
5 n L6 S4 i2 J6 j6 U+ u$ [ t; A3 {在这里本人推荐使用‘绝招’。 |