加速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的规则
二、 遵守三条规则1 f; y" n! K' N& w$ W4 `. e& Q
三、 绝招
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/ 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条:
1、只有使用以下数据类型,matlab才会对其加速:
logical,char,int8,uint8,int16,uint16,int32,uint32,double
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
re,single,
function 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循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值0 p f1 _) ]3 b: c. D+ u
来表示;
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
据类型,只使用
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
加速运行。5 A6 C) [5 p, ]) h% d
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
x = a.name; for k=1:10000, sin(A(k)), end;
6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速: 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
运行速度。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%6 F/ P! t0 v- o9 X7 x$ ?$ S. K! M2 y
%%%%%%%%%%%%%%%%%%%%%%%% W- ]; [# q8 r! H) U) t/ j
二、 遵守三条规则
1、尽量避免使用循环,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
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
for and while loops to equivalent vector or matrix operations.”。改进: L2 v- {0 u* Z( d. d$ ]
这样的状况有两种方法:
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
i=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);
end
替换为:
t = 0:.01:10;9 O j8 y2 S1 B( a. C3 N3 e
y = sin(t);" O% ]9 `- b1 m6 r: Z
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i' R' ?4 f5 D& w: `8 o. U5 J2 H
permute、permute、
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums2 ?2 g) ~2 {/ {( y( h
um、ind2sub、' p# @! h( i+ t% F" h& p: k7 ^& _$ N/ {
ndgrid、repmat、sort、sum 等。 o) J# d; k8 b/ w! U0 z6 {
请注意matlan文档中还有这样一句补充:“Before taking the time to
vectorize your code, read the section on Performance Acceleration. @" K! B9 f4 t0 T
You may be able to
speed up your program by just as much using the MATLAB JIT Accelera
tor instead of( j8 r# ^$ V5 G* S8 x- G) K: ^
vectorizing.”。何去何从,自己把握。
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
行循环次数少的,; O7 P& ?+ p5 W) B* u" n3 ^* a6 B
内环执行循环次数多的。这样可以显著提高速度。0 A+ j7 Q8 `, \& R7 l; a
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
es、cell、struct、
repmat等。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 ]. }
换成:
A = repmat(int8(0), 100, 100);( e- [; `; u X5 w# T% t6 m$ |' u4 I
c、当需要扩充一个变量的大小、维数时使用repmat函数。& u! G0 W: x. a
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
b、使用Functions而不是Scripts 。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* P+ Y- r# M) H3 @' |
%%%%%%%%%%%%%%%%%%%%%%%9 T1 }, O4 Z3 \+ x8 N' c2 S
三、 绝招
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
1、改用更有效的算法
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |