EDA365电子论坛网

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

作者: mm58690    时间: 2018-9-10 15:38
标题: 加速matlab运行的三重境界
一、 遵守Performance Acceleration的规则
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将% n* d% ]% W) D4 K; `
其规则总结如下7条:0 ~4 P0 Y( K) R+ c% }% r( O
1、只有使用以下数据类型,matlab才会对其加速:
/ J+ O; x7 {. t# hlogical,char,int8,uint8,int16,uint16,int32,uint32,double
  y4 _7 l( Z) V1 o而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu" K5 b( z4 y, Y0 M
re,single,
function handle,java classes,user classes,int64,uint64
! g: e  V* i" o2、matlab不会对超过三维的数组进行加速。2 p) y: S9 w: K6 D, l6 T4 X4 J3 O( P
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值* S8 C9 ]7 g' x7 n
来表示;+ K5 k8 t+ A/ [  ?; B4 Y% F
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
$ a0 |9 w/ R, j; K/ e+ I" v据类型,只使用
" g6 I0 F, Y' k. z* [/ s三维以下的数组;c、循环内只调用了内建函数(build-in function)。
. ?/ s' F( f% k/ @  m. ]4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将' q  c/ t& u4 {6 }/ g* C
加速运行。
! A9 _1 V7 ^2 G6 Q4 ?7 z% n- w5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:- Y7 m# k- K2 d. |2 O
x = a.name; for k=1:10000, sin(A(k)), end;
2 b; i4 A+ s7 J) z" M1 l. l/ W6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速  T6 G& o4 S" i9 O* S* C. l
度。
! m9 h; L. U* ]" n) k, _7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低  U9 Z3 Z5 H' s" \) v* J9 i
运行速度。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$ z3 k/ S: u5 {. }' c7 S1 D
%%%%%%%%%%%%%%%%%%%%%%%
; `  r# Z; V" L二、 遵守三条规则
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic7 F; @1 Y/ L, \0 X9 P+ M( `$ p
h means it is designed
for vector and matrix operations. You can often speed up your M-file c& d: m% R; p" d: z( C: S6 f3 o6 u
ode by using
0 U) x; d% [' Svectorizing algorithms that take advantage of this design. Vectorizati& b: b# M  P$ d& T3 P  _
on means converting3 ?, {: L; \1 n! s0 s  x
for and while loops to equivalent vector or matrix operations.”。改进) B* R# e: g& V, ?
这样的状况有两种方法:
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
i=0;
9 R) m/ k0 x' G0 K) Zfor t = 0:.01:10
( \' a2 L3 ~" Y+ @i = i+1;
8 K0 E4 g9 P1 ly(i) = sin(t);* _2 Q" B! U/ \  D" l. i1 Y
end3 o; K4 b/ L+ w9 M% ~" N
替换为:* d4 z3 F" K2 ?, n
t = 0:.01:10;
! m% q' t; w/ q( ~9 Ty = sin(t);
$ |  g% D0 q' j& p# l9 q6 z3 F速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i
( e  y- l+ w# epermute、permute、
' j* m6 R/ I" F( n; D9 preshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums# e4 r; Q  z4 \1 Z  T* s  w
um、ind2sub、
% l7 G) z2 E) U/ lndgrid、repmat、sort、sum 等。
请注意matlan文档中还有这样一句补充:“Before taking the time to
vectorize your code, read the section on Performance Acceleration.
/ W8 N9 K+ u* q' z! c; v9 b5 wYou may be able to
5 Q! d# }3 @2 C  nspeed up your program by just as much using the MATLAB JIT Accelera' K) b% x- @% X" n  A/ f& \! s
tor instead of2 Q: f! d& d% b9 G5 R
vectorizing.”。何去何从,自己把握。
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
% W- f  y! [1 |5 z" T# A行循环次数少的,; o+ }2 A1 w  w4 f
内环执行循环次数多的。这样可以显著提高速度。
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
9 |. `5 X  c: D! B0 Q0 a1 pes、cell、struct、! Y! f7 R# l+ B+ X  C7 @5 S
repmat等。
7 x9 Z8 K9 Y3 d- V; x3 fb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
A = int8(zeros(100));8 K5 l5 u1 }& @
换成:
6 z+ U& o5 {0 u1 T: N9 oA = repmat(int8(0), 100, 100);
2 e2 Y+ h6 B, {, n! y! qc、当需要扩充一个变量的大小、维数时使用repmat函数。
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。8 U8 d4 f$ _; |, k& S4 d& a
b、使用Functions而不是Scripts 。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%' p: q" @/ M9 d5 K
%%%%%%%%%%%%%%%%%%%%%%%1 ?4 i% G$ E3 K% {
三、 绝招
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
% R: h& Y9 O+ |' {0 F& w& A1、改用更有效的算法
5 @  X- K8 ]* {) v# d* H# W2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
4 q7 t9 ^+ g# M" d; H3、如果循环比较大的话,将循环部分改成dll调用会快50到100倍,大家试试吧

2 O6 H+ y4 k* I! H) s. T5 ?, E1 h* L
作者: mm58690    时间: 2018-9-10 17:30
谢谢分享




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