EDA365电子论坛网

标题: 加速matlab运行的三重境界 [打印本页]

作者: mm58690    时间: 2018-9-10 15:38
标题: 加速matlab运行的三重境界
一、 遵守Performance Acceleration的规则
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
4 Z' h  f$ H  ]. [其规则总结如下7条:
) h1 }4 W! q3 c& ?( A& a$ N; N4 p6 ~1、只有使用以下数据类型,matlab才会对其加速:+ Y  m" Z% j7 ~' c$ _  i2 h5 g+ t+ ]
logical,char,int8,uint8,int16,uint16,int32,uint32,double' X3 H% ]- |$ X1 T4 i$ B5 M& H) w
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu; Z, q7 L& J# p$ P
re,single,
function handle,java classes,user classes,int64,uint64- _+ O( a7 B2 \$ E/ h: [# c8 w6 Q
2、matlab不会对超过三维的数组进行加速。
7 v# I4 a* O  y; t2 j, O, `/ P# e3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值, u* o- G( ]4 V: b+ t
来表示;& Z2 U* I) k8 P* C# }+ ?. j
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
! A9 W2 Y  P  e, d3 F) {* Y据类型,只使用5 Q) j: u% o9 w$ A3 s
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
* U. d# E) i, N$ H  Z. y4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
5 ~5 H0 Y, B, }. G4 ~加速运行。' Q: b% y' R; @$ l1 q) M
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
( ~- \1 \" H* o: n- `* mx = a.name; for k=1:10000, sin(A(k)), end;
; n1 t7 O6 E/ q/ q. t  ]. g, |6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
) Y$ \" H  d7 r' d. M( t, z4 p度。
, I- T6 r$ Z; ~/ [8 ]! n5 R7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
* ?, `% b. s( z' y5 J运行速度。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%( h3 c# t" ~' b, f$ ]/ G, B
%%%%%%%%%%%%%%%%%%%%%%%
- ?: C' c6 B+ w) P- @% n! B. J) g二、 遵守三条规则
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic
7 F" ^- w0 a' r" Jh means it is designed
for vector and matrix operations. You can often speed up your M-file c0 b6 I4 n9 W8 ^6 Z4 B* B: P
ode by using! d) e# h+ g  j2 T& s
vectorizing algorithms that take advantage of this design. Vectorizati
9 i9 @9 Q) I; V* R1 o$ N: Xon means converting
' \' [, I3 s' N8 X! C/ bfor and while loops to equivalent vector or matrix operations.”。改进
( a2 R/ N6 B9 ]2 ^; N2 e这样的状况有两种方法:
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
i=0;
' m1 P$ S9 w& b/ Qfor t = 0:.01:10$ c5 Z( M0 R" E- ~- k/ V
i = i+1;
% k0 p( h! l" ?y(i) = sin(t);
6 @% e, M$ ~$ n! [/ m/ dend
" z7 d8 x: C/ F2 X0 \5 K替换为:
) {* x  w7 t. _' j0 C) i3 Xt = 0:.01:10;
$ q/ @* g% @9 h4 }: Ty = sin(t);
' w- x: s( f; j9 r! }- ?0 b2 r; k速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i
  u% U& W5 s$ bpermute、permute、
! R+ F2 n# I" L" preshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums
. h8 r$ \1 l# B* h" v6 v1 ?7 ^um、ind2sub、
; w! j1 |+ a+ K; s) ~' Mndgrid、repmat、sort、sum 等。
请注意matlan文档中还有这样一句补充:“Before taking the time to
vectorize your code, read the section on Performance Acceleration.
: `. }4 e2 s  x* P6 pYou may be able to
3 y! `7 O' A) x  b) i2 Uspeed up your program by just as much using the MATLAB JIT Accelera; u1 W+ i2 J. y0 t' ]9 G$ X; |) {
tor instead of
3 y( A8 {& O* P/ \$ P9 f: z/ o0 P: s, B. hvectorizing.”。何去何从,自己把握。
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执$ f  m$ z4 C% B# k# L: P
行循环次数少的,
' B& H8 E; ^5 }0 O, f+ I8 R) l内环执行循环次数多的。这样可以显著提高速度。
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
* W" |! ]4 w+ ]5 yes、cell、struct、
+ n/ T" e& \0 ^9 d1 M, K5 k9 {+ [repmat等。
+ n- m) [6 _* {7 ]5 @) ib、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
A = int8(zeros(100));
$ ]' ~- d: w/ j/ S) l: u换成:5 N8 }1 t6 T' j9 s8 L
A = repmat(int8(0), 100, 100);
' j$ U7 _9 R2 [( c' ?8 Vc、当需要扩充一个变量的大小、维数时使用repmat函数。
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。* G4 K+ G! O: M* Z! p% p( I% L9 m% d' q
b、使用Functions而不是Scripts 。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- T) Q3 k& d; R( ?5 M, L%%%%%%%%%%%%%%%%%%%%%%%) p8 M. G4 P" @2 N4 f
三、 绝招
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
+ v( s$ _0 [9 B+ N4 E+ c1、改用更有效的算法: x+ p6 L: a; H& `; X/ t3 t
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。# a- G- v+ f# T; ^6 Z# S
3、如果循环比较大的话,将循环部分改成dll调用会快50到100倍,大家试试吧

  z, ~5 _3 ?3 }2 Q) s4 [
作者: mm58690    时间: 2018-9-10 17:30
谢谢分享




欢迎光临 EDA365电子论坛网 (https://eda365.com/) Powered by Discuz! X3.2