加速matlab运行的三重境界! t1 b0 S4 b/ r7 |: K2 ^) p+ b
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%
一、 遵守Performance Acceleration的规则
二、 遵守三条规则6 q" ], O6 d% u9 ?% O- D
三、 绝招
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%
一、 遵守Performance Acceleration的规则
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将8 g6 n" C. l3 \) f
其规则总结如下7条:
1、只有使用以下数据类型,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
re,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循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
来表示;' E, p9 k1 N# O0 H5 X* x& ^& F
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数2 c& `& E* @& d+ B+ A
据类型,只使用! S. Z' U, t8 t7 v
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
加速运行。8 S! Q; l& a% ^; y C
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
x = 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 [
运行速度。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%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
h means it is designed
for vector and matrix operations. You can often speed up your M-file c
ode by using
vectorizing algorithms that take advantage of this design. Vectorizati f9 w7 w* B. n) n- C9 k
on means converting
for and while loops to equivalent vector or matrix operations.”。改进* P K H& {' v# Z
这样的状况有两种方法:
a、尽量用向量化的运算来代替循环操作。如将下面的程序:9 {6 A8 ~" ]7 z5 J
i=0;, v/ D; \0 C( D6 d1 {
for t = 0:.01:10
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
替换为:
t = 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技术的函数有:All、diff、i6 d$ T! s7 H% S% ^$ y
permute、permute、$ A t4 m9 D6 w# _
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums" ~. g8 b: Y7 T; E+ D/ h# w
um、ind2sub、
ndgrid、repmat、sort、sum 等。/ D" g# }& ?& b/ p
请注意matlan文档中还有这样一句补充:“Before taking the time to
vectorize 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
vectorizing.”。何去何从,自己把握。9 e* `2 w$ v& m" ]
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
行循环次数少的,
内环执行循环次数多的。这样可以显著提高速度。( D" [: A$ d$ m7 a
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
es、cell、struct、6 y/ o$ F) ? m) o( S
repmat等。
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
A = int8(zeros(100)); j1 T4 Y( a$ L
换成:
A = repmat(int8(0), 100, 100);* t' {7 F4 ^/ v" b# \2 t. I
c、当需要扩充一个变量的大小、维数时使用repmat函数。5 J, N" N: [- ?3 y. X' H
3、a、优先使用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 ?) ~, ]
%%%%%%%%%%%%%%%%%%%%%%%
三、 绝招( X* u. Z4 L+ ^. k. T7 W& t1 G
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
1、改用更有效的算法
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |