数学建模社区-数学中国

标题: 【转载】加速matlab运行的三个境界 [打印本页]

作者: 厚积薄发    时间: 2010-1-25 22:39
标题: 【转载】加速matlab运行的三个境界
本帖最后由 厚积薄发 于 2010-1-25 22:54 编辑
( d- o  Q9 b2 M" \# }8 T+ a8 O4 h4 k; i* z
加速matlab运行的三重境界

加速matlab运行的三重境界" M8 ~: x6 H0 S
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" Y9 H8 I7 h+ j% ~9 d! C* K- w& a
%%%%%%%%%%%%%%%%%%%%%%%6 ?) ?; {8 b+ h/ P3 Y( w) @: c
一、 遵守Performance Acceleration的规则
" u/ Y9 j& r* g  ~! G+ u二、 遵守三条规则1 f; y" n! K' N& w$ W4 `. e& Q
三、 绝招
6 e+ @2 |+ A  b6 T' a7 A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/ f2 y4 ]$ w# |* ?( a
%%%%%%%%%%%%%%%%%%%%%%%

一、 遵守Performance Acceleration的规则. i$ u- Q  Y  |) x, Q% H5 Q, [4 o/ ~8 H% l
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将. a, v; Q' @* K  U+ D) D7 }
其规则总结如下7条:
% i5 g# h, n+ f1、只有使用以下数据类型,matlab才会对其加速:
, }  t* Q7 o; b1 O3 D5 s& mlogical,char,int8,uint8,int16,uint16,int32,uint32,double
1 X) D) K1 j) `, [5 E/ _
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
) x9 ]3 ~* x3 T4 T& c3 `  G; tre,single,
8 L+ t- @( K0 Wfunction handle,java classes,user classes,int64,uint647 O% q* h9 X8 j9 }+ J( m7 b4 C& j
2
matlab不会对超过三维的数组进行加速。
% S0 o( [1 Q# x1 }- r9 P
3、当使用for循环时,只有遵守以下规则才会被加速:afor循环的范围只用标量值0 p  f1 _) ]3 b: c. D+ u
来表示;
4 _  R2 w7 G6 M! `bfor循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
) r; Z! F) p1 u9 h据类型,只使用
( Z" m1 y' m) ^: Y7 C# O! V* ]三维以下的数组;c、循环内只调用了内建函数(build-in function)。
' k, j( x, T' k( L( F9 y4、当使用ifelseifwhileswitch时,其条件测试语句中只使用了标量值时,将
3 g0 D+ D- \5 a  C9 V) m0 L加速运行。5 A6 C) [5 p, ]) h% d
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
5 r& t1 K- h5 }& i/ s* B# {x = a.name; for k=1:10000, sin(A(k)), end;
8 Y( y# T2 S9 X$ R% c6
、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速: B! f- r, j5 j
度。/ T8 _9 n$ p: F+ j
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低; w  ]) t! f2 I" }" O) v
运行速度。
3 X2 L6 Y2 I* A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%6 F/ P! t0 v- o9 X7 x$ ?$ S. K! M2 y
%%%%%%%%%%%%%%%%%%%%%%%% W- ]; [# q8 r! H) U) t/ j
二、 遵守三条规则
. X) t* ~0 d8 j2 O1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic2 |+ ~' N2 }0 F
h means it is designed, q* e, m: K( {% F% K# t
for vector and matrix operations. You can often speed up your M-file c
, B- ^7 q* ?' _ode by using0 r0 i. g  `, |2 @; e% z
vectorizing algorithms that take advantage of this design. Vectorizati: m9 \! s) R. y6 o: _* y( T- g- N
on means converting
; a+ C% N! J$ Z8 f( Y/ x9 F: _for and while loops to equivalent vector or matrix operations.”
。改进
: L2 v- {0 u* Z( d. d$ ]
这样的状况有两种方法:
9 x# g* Q/ a9 v; K7 ]a、尽量用向量化的运算来代替循环操作。如将下面的程序:
- E3 ]0 J% A4 k, r3 Z; Q3 y* Ei=0;, ], a, |+ V* ?7 i* F+ }7 }
for t = 0:.01:10# p" R( T( d2 H3 q8 @
i = i+1;  [7 n! F- g: x# w% A
y(i) = sin(t);
, {7 P3 G7 \& A- q3 o0 Yend
( @4 j3 L: Z  K- @
替换为:
0 r8 @; V% r0 v1 J4 et = 0:.01:10;9 O  j8 y2 S1 B( a. C3 N3 e
y = sin(t);" O% ]9 `- b1 m6 r: Z
速度将会大大加快。最常用的使用vectorizing技术的函数有:Alldiffi' R' ?4 f5 D& w: `8 o. U5 J2 H
permute
permute

5 n2 n' K: F: L% X2 Vreshapesqueezeanyfindlogicalprodshiftdimsub2indcums2 ?2 g) ~2 {/ {( y( h
um
ind2sub
' p# @! h( i+ t% F" h& p: k7 ^& _$ N/ {
ndgridrepmatsortsum 等。  o) J# d; k8 b/ w! U0 z6 {
请注意matlan文档中还有这样一句补充:“Before taking the time to
: N/ L( ^$ U) N8 x, Z$ @vectorize your code, read the section on Performance Acceleration.  @" K! B9 f4 t0 T
You may be able to
5 v) Y9 D  J+ ]! }7 n! m+ r4 J) xspeed up your program by just as much using the MATLAB JIT Accelera
1 H& C" t) w, k  b+ etor instead of( j8 r# ^$ V5 G* S8 x- G) K: ^
vectorizing.”
。何去何从,自己把握。

6 `$ Y& R: c9 y+ F1 ^& Ob、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
2 x4 i$ ^: b. c6 }. S2 i6 z行循环次数少的,; O7 P& ?+ p5 W) B* u" n3 ^* a6 B
内环执行循环次数多的。这样可以显著提高速度。0 A+ j7 Q8 `, \& R7 l; a
2a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeroson
2 F% }; X1 {4 C$ \5 O; des
cellstruct

7 S" H/ O+ Y# p- }+ Irepmat等。0 L  G* k; x6 u+ }& C
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:/ {& P3 [  F% X4 U
A = int8(zeros(100));1 D8 @- a7 X2 C" i' u8 ]. }
换成:
1 x$ i/ J( o! L8 @$ J% f1 KA = repmat(int8(0), 100, 100);( e- [; `; u  X5 w# T% t6 m$ |' u4 I
c
、当需要扩充一个变量的大小、维数时使用repmat函数。& u! G0 W: x. a
3a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
" {4 ~5 I. \, Q2 e( Q6 P# S8 r! wb、使用Functions而不是Scripts
% X9 n, Q5 h0 N$ h" T5 H%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* P+ Y- r# M) H3 @' |
%%%%%%%%%%%%%%%%%%%%%%%9 T1 }, O4 Z3 \+ x8 N' c2 S
三、 绝招
( V( O$ ~& D1 Z1 {' o$ ?& i% |你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
( N& H3 m# ]2 z1、改用更有效的算法
  C5 W3 y: e" ?5 q2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。

: O7 l4 c5 I2 H& o* ?
8 P- y, ~6 U! P& M  ~$ F( [% _
  来源:iLoveMatlab: |* s/ t# z- I4 ]
' E! K. t- J/ i( j& F2 q0 O
2 q& N$ Y4 ^3 h% P/ o' u$ J+ K/ [5 y
在这里本人推荐使用‘绝招’。
作者: XINGQIBIN    时间: 2010-1-25 22:42
请注意matlan文档中还有这样一句补充:“Before taking the time to
作者: HSinB    时间: 2010-1-25 23:40
收藏了,感谢楼主!!!!!!!!!!!!!!
作者: D-lin    时间: 2010-1-26 00:18
好牛啊 从来不知道的 思密达 。。。。。。
作者: leo12ok    时间: 2010-1-26 08:50
相对于楼主,我更倾向于绝招之外的方法,呵呵。
作者: xiaoding123    时间: 2010-1-26 08:56
必须好好研究一下matlab了~~~~~~~~~~~~~~~~
作者: isnowfy    时间: 2010-1-28 18:33
mark。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
作者: yansichong    时间: 2010-8-26 18:32
收藏了~~~对现在建模很有用……我上次写的程序就运行了N久都没出结果……郁闷……
作者: schnee    时间: 2012-2-6 17:26
顶!!!!!!!




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5