信人: fork (撒哈拉沙漠的沙), 信区: Matlab * [2 ?5 S. s5 i标 题: 加速matlab运行的三重境界 6 g1 u4 D5 @8 G C# a发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004) + b$ S, y9 h5 g1 |" o5 B, t, o: p. t8 ^0 v
加速matlab运行的三重境界 & V4 O$ m# ?, n: J* q l 4 f4 R" P* {3 x# W2 {( }%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%) y0 b: |7 G9 k4 |
%%%%%%%%%%%%%%%%%%%%%%% ' T5 F! Z0 T4 W- F一、 遵守Performance Acceleration的规则 [$ n3 T1 K+ X1 v* P二、 遵守三条规则) k, f) n6 i) |: ^, V/ q# V
三、 绝招- F# q0 o9 U* \3 Q! x' e
+ ]' h- {/ B: g7 h2 a; @% |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%. j* l! r% B9 w! O
%%%%%%%%%%%%%%%%%%%%%%%' l$ }/ N: F0 v
一、 遵守Performance Acceleration的规则 % T Y. G# i" G0 [& D3 v w! V! W' _2 N" j/ E! h
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将 : s+ p- h4 `0 \+ H其规则总结如下7条: ; e7 F' O# r% [1、只有使用以下数据类型,matlab才会对其加速: . s9 } }& n6 O6 klogical,char,int8,uint8,int16,uint16,int32,uint32,double P' m( k. q' Y8 V: Z7 m, d/ A而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu: A1 j0 G9 P* P+ O
re,single,3 M# S3 c+ b d" `' g6 s' y
8 j. k/ @7 R9 i
function handle,java classes,user classes,int64,uint648 j* Z, @ r/ e! x- f
2、matlab不会对超过三维的数组进行加速。: ^7 Z% @% ~+ z: i
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 7 A$ j; w: [" R) k( i来表示;6 b7 c. V2 ]. L9 {, k) ~. g
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数. E* m. V& |2 s" K7 D
据类型,只使用7 E0 x! F' d& z* ^6 t P
三维以下的数组;c、循环内只调用了内建函数(build-in function)。 3 N1 F. ]3 M p: _8 [% a- x* u4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将 ; Y9 C; k/ N. x; p加速运行。 ' Z( F* G& `# S% ?5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:& l2 W2 p9 b0 z' y) w/ g
x = a.name; for k=1:10000, sin(A(k)), end; s* O% d( ?) e6 a( ^6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速 2 Q3 U1 m6 M9 D2 C度。2 O8 O, y( a) X k9 ^% @
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低 & c4 Q# f7 Y, B$ r T }运行速度。 6 M9 j0 l3 {. J3 n5 \) S/ L* j; g) R, t5 ]3 T( j
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%, F1 H) i/ g5 h
%%%%%%%%%%%%%%%%%%%%%%% 2 m2 ?( c/ v8 M& p二、 遵守三条规则8 x4 O7 j% Y# ~4 j& y: H
, `6 I/ I# M, ~/ K9 G
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic 0 A/ l* T' A8 q! e2 Vh means it is designed& F+ {/ V7 w& Q, _
& v+ u6 w1 E: N1 L" ^for vector and matrix operations. You can often speed up your M-file c9 w# z" @8 q. j
ode by using7 e& ^9 V3 M2 F
vectorizing algorithms that take advantage of this design. Vectorizati( Q" u3 [: [8 I
on means converting 1 q- N$ a' n; X/ n' Y, Afor and while loops to equivalent vector or matrix operations.”。改进9 p3 |/ F5 Z8 Y
这样的状况有两种方法: & O( q; Q5 E) s6 @8 U1 H$ g ! [/ D$ [7 i6 i) c, _) a& |# Q5 xa、尽量用向量化的运算来代替循环操作。如将下面的程序:/ h! m7 Y! t' A/ B
6 S' v- U/ N# ~9 r2 ?3 L. R5 g% b
i=0;6 V% s7 i0 m- ^
for t = 0:.01:10- y1 ]( t+ c6 k( t2 g" S
i = i+1;' v+ S5 O$ b" }6 {& a7 V
y(i) = sin(t); : x j, t+ O4 b' c$ p" M( r( T0 \end$ L+ a9 D" ^3 O# O+ C
替换为: / l0 o( r1 O. D# S9 Kt = 0:.01:10; $ \0 M( c! [) My = sin(t); 1 v; M. v5 P t8 Z速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i, B4 N% X# I! a" z& z+ Y7 t
permute、permute、8 f; ?) I3 c# `$ }
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums( g' O# M- d( ^" J& }" [
um、ind2sub、 2 D# c2 _5 f/ \. l2 zndgrid、repmat、sort、sum 等。4 _) D) P* ^ i
2 ^9 q; I; U) @8 o' a
请注意matlan文档中还有这样一句补充:“Before taking the time to 3 ~) T, d/ T" O: u' y d) h; i5 i' t1 M$ o
vectorize your code, read the section on Performance Acceleration. % j- E3 E" y6 Z0 z8 F: vYou may be able to$ N3 g( o8 z- }. k/ \
speed up your program by just as much using the MATLAB JIT Accelera 9 E4 v, c& z w) mtor instead of4 ^8 w5 A8 C. J" E; a/ [
vectorizing.”。何去何从,自己把握。 7 l4 |% g. e [* e! V( }. t3 k0 a0 y$ r* @/ G: n
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执 u0 ?* ]* N+ H& I: N8 A$ z7 M
行循环次数少的, 3 }& T- M/ ^4 n; {! z/ q) x内环执行循环次数多的。这样可以显著提高速度。 * I" A1 ]4 _9 p% E( Y1 N( ^9 n# v6 n) a; X- g
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on- G/ R: w& m1 M8 v" [. r
es、cell、struct、 . I% b% K* O- @% c7 U" Prepmat等。 : R/ F3 [. K; `7 p7 vb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码: 0 a/ d5 ^' B# P2 j- g) m, b* y- v* p6 K+ k
A = int8(zeros(100)); - U4 v o$ N: X: D5 k- e/ N2 ]换成: ' ~: D- R8 s- [& h/ x& x' q0 yA = repmat(int8(0), 100, 100); ! q7 C. a# ?6 L1 @6 h) hc、当需要扩充一个变量的大小、维数时使用repmat函数。 8 }/ {. t% H C& c0 Y' f2 S* M 3 X ]: G+ i5 e& K! k( G, K3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。 & r6 E- j* _8 d+ V+ ~b、使用Functions而不是Scripts 。 8 ~! [! |7 A+ {9 |- M$ Z: Z4 j. E, ~
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%7 |* A: F m4 ^' E# t4 I
%%%%%%%%%%%%%%%%%%%%%%% j- t& p7 y, X) a* s, m. w
三、 绝招9 l& ?9 Y- d; n" ?7 ?0 d$ y6 A, q
7 p. @0 k% @, G4 p你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。, t1 K/ e) ?: B6 W
1、改用更有效的算法% H! A5 `0 t3 a, ^9 c
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。* F! \6 ~- j! o `+ V+ Y