数学建模社区-数学中国

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

作者: 厚积薄发    时间: 2010-1-25 22:39
标题: 【转载】加速matlab运行的三个境界
本帖最后由 厚积薄发 于 2010-1-25 22:54 编辑
1 D+ R/ Y* c5 ]) {1 L# Z7 y! U4 h
: x3 J6 S/ ]; u# C0 M5 y) X加速matlab运行的三重境界

加速matlab运行的三重境界! t1 b0 S4 b/ r7 |: K2 ^) p+ b
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
: N  I3 \% A6 r. Z%%%%%%%%%%%%%%%%%%%%%%%
/ M  A# w$ v( O! l! h8 P  u3 f
一、 遵守Performance Acceleration的规则
7 M, m# }" [  B2 `; j. t6 P. I+ w. {二、 遵守三条规则6 q" ], O6 d% u9 ?% O- D
三、 绝招
7 f" m+ {7 _  K$ M2 K%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/ i9 f$ {: v; ~$ J%%%%%%%%%%%%%%%%%%%%%%%

一、 遵守Performance Acceleration的规则
& @/ B( |, c+ y8 U6 o关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将8 g6 n" C. l3 \) f
其规则总结如下7条:
/ {! q0 i* w" C1 i/ m% Z& u, H1、只有使用以下数据类型,matlab才会对其加速:9 A4 g" y3 z8 ?5 B- @7 K
logical,char,int8,uint8,int16,uint16,int32,uint32,double9 @4 T" m  r' G2 D3 c
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
8 B9 [) O! B) a" u- l3 W& {8 Qre,single,* r! G% s8 b6 b! o6 P) J
function handle,java classes,user classes,int64,uint646 b7 P+ X) c5 ]/ m3 M: @
2
matlab不会对超过三维的数组进行加速。
3 q4 v" F7 B' f" G9 N* i1 @
3、当使用for循环时,只有遵守以下规则才会被加速:afor循环的范围只用标量值
+ e7 ?: I" w+ s2 M' X来表示;' E, p9 k1 N# O0 H5 X* x& ^& F
bfor循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数2 c& `& E* @& d+ B+ A
据类型,只使用! S. Z' U, t8 t7 v
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
2 l# D( A, }( D' D7 g4、当使用ifelseifwhileswitch时,其条件测试语句中只使用了标量值时,将
2 ^0 e* a& K+ s' y5 F2 P" k( j1 Y( q加速运行。8 S! Q; l& a% ^; y  C
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
! q  m' U, c8 B; M: S  ?5 [1 Lx = a.name; for k=1:10000, sin(A(k)), end;: S; b; [4 n6 a
6
、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速' _  A# _, O1 j! \* ^9 A- X/ y) k+ Q
度。' D- a, R+ I1 o  S7 p7 ^" ^
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低+ ~- o/ I* w; J% u1 [
运行速度。
9 o, X* r' s) a4 z2 X  g%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%8 }8 z  k3 T& N5 M6 m
%%%%%%%%%%%%%%%%%%%%%%%9 z1 w% E, K/ S$ Z' f4 z
二、 遵守三条规则6 b+ @9 [: [. {! O: L5 e
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic
: ?& J/ ^# ^; f& S' ]: {h means it is designed
( |$ U0 l; F# T/ pfor vector and matrix operations. You can often speed up your M-file c
( i) g$ F* c( i" _4 Q* Lode by using
! K9 x4 J. t- m: S- }5 {vectorizing algorithms that take advantage of this design. Vectorizati  f9 w7 w* B. n) n- C9 k
on means converting
; Y1 s* y) ?- d, v" sfor and while loops to equivalent vector or matrix operations.”
。改进
* P  K  H& {' v# Z
这样的状况有两种方法:
' y3 i" I+ l/ H$ H# Y$ N. }a、尽量用向量化的运算来代替循环操作。如将下面的程序:9 {6 A8 ~" ]7 z5 J
i=0;, v/ D; \0 C( D6 d1 {
for t = 0:.01:10
$ k& n% v0 a7 F3 ?i = i+1;  M7 d+ f5 M' ~- b
y(i) = sin(t);+ P4 m* k" C0 N
end2 t! ~7 C# p7 T: }9 K) M
替换为:
* z% z, t8 O/ F6 pt = 0:.01:10;3 v- F& m) r; I) ~4 T! }
y = sin(t);6 b0 L" S. ]0 j/ S  {2 ^1 u: m
速度将会大大加快。最常用的使用vectorizing技术的函数有:Alldiffi6 d$ T! s7 H% S% ^$ y
permute
permute
$ A  t4 m9 D6 w# _
reshapesqueezeanyfindlogicalprodshiftdimsub2indcums" ~. g8 b: Y7 T; E+ D/ h# w
um
ind2sub

5 w! y7 R4 j' b" Z! w0 fndgridrepmatsortsum 等。/ D" g# }& ?& b/ p
请注意matlan文档中还有这样一句补充:“Before taking the time to
. K# l; m0 Z- |9 X5 S# Xvectorize your code, read the section on Performance Acceleration., @& P: N0 M4 b  d" v) F8 h
You may be able to' }5 }: R* m; A, B2 u
speed up your program by just as much using the MATLAB JIT Accelera7 s4 \. A/ l$ E3 X% @+ {  e
tor instead of
5 i$ a* I  P! B1 Z6 Uvectorizing.”
。何去何从,自己把握。
9 e* `2 w$ v& m" ]
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
2 a1 q! q0 S, K- o$ z% [行循环次数少的,
4 o( i7 \1 ]! F; r0 j' L& G内环执行循环次数多的。这样可以显著提高速度。( D" [: A$ d$ m7 a
2a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeroson
, j( \  k: Z1 Res
cellstruct
6 y/ o$ F) ?  m) o( S
repmat等。
9 q7 Z* g, R; q% ~% Bb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
5 W: u: G5 z+ _, {9 AA = int8(zeros(100));  j1 T4 Y( a$ L
换成:
, F  F; ?* S0 ~  {" cA = repmat(int8(0), 100, 100);* t' {7 F4 ^/ v" b# \2 t. I
c
、当需要扩充一个变量的大小、维数时使用repmat函数。5 J, N" N: [- ?3 y. X' H
3a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。3 a: t. `7 y- h; O! z
b、使用Functions而不是Scripts ) U9 a3 Z5 n: C0 R+ t0 t
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%9 @* G* V# r! f; k6 l0 ?) ~, ]
%%%%%%%%%%%%%%%%%%%%%%%
2 [9 C0 U6 y) R5 D% Q6 C
三、 绝招( X* u. Z4 L+ ^. k. T7 W& t1 G
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
' u: K/ g9 a# {2 w) h: b6 t1、改用更有效的算法
' R- }0 o9 T, s+ h* ^2 D3 @+ h7 A2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。

. X9 u/ _1 o' v# y) o# O4 i

6 h4 Q; z& d. l  来源:iLoveMatlab1 M" T1 z+ D! e7 Q4 y( G* y
# m8 p# |! r: }! i$ e& P. x* [0 c

) ]; c. q3 O- N在这里本人推荐使用‘绝招’。
作者: 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