信人: fork (撒哈拉沙漠的沙), 信区: Matlab ( t- y0 i6 H* R, }% j% y2 z0 Z标 题: 加速matlab运行的三重境界 _( K8 k3 z; h. G: S发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004) ; J: F0 b. @( ?6 R( P- C: f' {# B9 {+ X9 M- p& c
加速matlab运行的三重境界 5 e& `3 A3 V2 {' l% }0 Z9 o7 T8 ~; ^# h6 S1 t) U
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * P; |* Z) w! N9 L8 W3 A%%%%%%%%%%%%%%%%%%%%%%%$ `. Q/ C, l" u' C5 a
一、 遵守Performance Acceleration的规则 0 h; Q- D* c/ d! T. U二、 遵守三条规则5 ?& P# ]" O" c
三、 绝招$ d: v: s R) ?( }# C9 [& i
2 L6 G* D+ R: E- s& ~
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ( M4 I. h. J3 P4 g5 Q: R# x- A2 R%%%%%%%%%%%%%%%%%%%%%%% 0 P2 ~; y5 u' j一、 遵守Performance Acceleration的规则 : H& J2 [: e1 L# a* V6 H& g 5 b# Y) W9 k0 n3 F; c7 f# E关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将 " E' o @0 J6 Y0 B$ b9 J其规则总结如下7条:& t% N% G8 j4 |/ d# S$ @7 u
1、只有使用以下数据类型,matlab才会对其加速:) B, y# p- t! N2 |3 b8 [- E
logical,char,int8,uint8,int16,uint16,int32,uint32,double" a- n2 B* L: n% G9 |2 b
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu7 m' S( l: S* A: ` A
re,single, $ |% @7 [( D* |. y2 S; j ( j7 r# w" f" c: i3 w$ U" Kfunction handle,java classes,user classes,int64,uint64 ! g1 r% N- i4 x( B/ V. S" K9 U2、matlab不会对超过三维的数组进行加速。8 j d2 i0 r4 y) j
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 ' u7 |7 l0 q, Z, y% q来表示; 7 |5 @: F4 _$ ~ M( Kb、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数- C( S) y6 O# R& m
据类型,只使用 / ?$ w! e f! D: X* U# n三维以下的数组;c、循环内只调用了内建函数(build-in function)。 & w7 V# c* m; D4 E1 F6 z4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将 - [. h) j9 G/ \/ U! m加速运行。( v1 `" R7 Q4 A9 f
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:0 \3 Z r* |2 o; X2 T$ X
x = a.name; for k=1:10000, sin(A(k)), end;% }5 j3 q1 A) G" J' s$ u
6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速2 n1 C) a _- B. p9 |! X0 u
度。- U M1 N. f# @
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低 ) k: J" W+ j( {4 I6 L! d运行速度。 ( I+ l6 T0 F4 M* y / I" [+ v: w. H%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+ \4 j: `! r9 k( j# _" M+ M
%%%%%%%%%%%%%%%%%%%%%%%) S, s- g4 m- M/ n w! p
二、 遵守三条规则* |. ~' @8 ]/ @/ m% i
& A7 E3 G9 P- \& ^
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic* o# o* x# u% I( Q
h means it is designed; G; }! u. D8 m
0 f/ R9 @5 Z# o8 H1 I7 qfor vector and matrix operations. You can often speed up your M-file c ' s/ D% c7 A" V1 T) Rode by using! [0 P% s7 m$ J! t& F
vectorizing algorithms that take advantage of this design. Vectorizati - R7 [% y) k a$ n: L" k3 a& L$ E" Aon means converting/ {) C5 D! ~5 e! g
for and while loops to equivalent vector or matrix operations.”。改进9 B- B/ ~5 x# |+ Q/ F
这样的状况有两种方法:: H: [! m6 u4 R- j/ a1 N/ J' m
6 Y/ U2 C8 m3 p P; o9 Q3 Ia、尽量用向量化的运算来代替循环操作。如将下面的程序: 5 U# V3 u) ?8 o. C0 t ! K. A; ~* y. W( R4 ]" _i=0; , Y4 Z* K" y1 m+ m0 [& Lfor t = 0:.01:10# ?; M [8 `: [; v0 }: t' q* Z, O
i = i+1;& j- N, A9 O* N+ V
y(i) = sin(t);; W/ b T, Z/ M3 g! ~
end ; c8 H; J3 ], ~+ P' k2 P8 x! V替换为:* P5 \+ M- f) r# M1 {
t = 0:.01:10; & z8 c+ T- @0 l6 Wy = sin(t); " A; X$ P. p$ v B速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i O. b2 H( V. N, ?permute、permute、- b9 L3 @7 z7 e0 S- r
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums& w* Z( E! L5 c5 Q4 _
um、ind2sub、4 S% ]0 y r6 I, J3 u: y
ndgrid、repmat、sort、sum 等。% N M' f) K) T/ b% P1 j
$ e6 ?5 f( K9 I9 }% h, W请注意matlan文档中还有这样一句补充:“Before taking the time to ; L* Z, H, z# h$ g k) c) ~) { i) k- q+ @$ ^+ A* T" H9 h
vectorize your code, read the section on Performance Acceleration.; Y4 R4 W7 h) a# C. I
You may be able to 8 s# m8 t! ^5 M% u9 O1 `speed up your program by just as much using the MATLAB JIT Accelera - k. j5 j+ u! a4 x+ e2 ator instead of+ P+ N$ F$ d# q( @! x* i& P
vectorizing.”。何去何从,自己把握。0 ]. z: q; O2 r
1 Z( M7 }" a" q( ~/ }; z- \
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执$ f' O0 a3 p; h; }4 L
行循环次数少的,/ k' q$ P8 z1 A# D; Y
内环执行循环次数多的。这样可以显著提高速度。) S. H6 p* R& c) M. \
! Q, C' I4 ]; y6 ?+ ^2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on7 X5 F h; n2 [1 o$ Z
es、cell、struct、 1 S" Z- N# q9 K5 b) qrepmat等。 2 g1 I& q+ k b, ~5 Ab、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:% f9 N$ K: @" U7 o3 N }; X
; l* Y; P% F4 Q5 U9 \A = int8(zeros(100));# z8 Z- Z- u1 k0 r+ Z* ]5 N* y0 L
换成:& @5 {" p9 M+ ?5 f* ^
A = repmat(int8(0), 100, 100); g1 {" t, k4 j" T8 K
c、当需要扩充一个变量的大小、维数时使用repmat函数。0 J$ a' o v+ ]4 v3 j! n
. f% b0 O, q( V3 ]' Y3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。+ b! J# \$ O- D5 I% C. j) h
b、使用Functions而不是Scripts 。 $ X% R9 e" ]0 X( {: S 0 P' e; J$ L; b$ G7 s+ ~2 A) a%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% & l$ K. O7 R3 M' @; V! i%%%%%%%%%%%%%%%%%%%%%%% . h; L1 L. [0 {' S5 [- f三、 绝招 7 W# t, X: T6 N) ]1 g- A/ d' ?9 S/ M# F) D# ^
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。 ( ]4 C3 ]; p. X1、改用更有效的算法9 |* `. X( U$ v# v' f
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。 % n0 C8 I$ U0 L! G2 v) g8 v6 G( D " Q) `- b8 s' _/ n' }关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++ ! \. A% j4 \9 Y d1 m' z0 p# k语言文件,VC编译