数学建模社区-数学中国

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

作者: god    时间: 2005-1-20 10:27
标题: [转帖]加速matlab运行的三重境界
信人: fork (撒哈拉沙漠的沙), 信区: Matlab
4 q4 A* _* C+ m. V: z+ ^0 _9 W标 题: 加速matlab运行的三重境界
. z, E3 X* S( `5 d0 W, `. V9 L发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)
, s7 Q7 @% l3 Y- M' F
1 m) X! [( Y1 z加速matlab运行的三重境界) b5 O- h7 D& M& f* s

3 r6 s9 m8 s3 N# `( P%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%& d" {5 C* |: ~; V
%%%%%%%%%%%%%%%%%%%%%%%
. Q3 L. u! o! P) a一、 遵守Performance Acceleration的规则9 E) S1 [/ t$ Q7 a6 b
二、 遵守三条规则
) i  f+ @7 ?; d, y三、 绝招* K3 C  O4 \" U

. B% T& r1 ^8 b- V$ x%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
! ?9 |1 x$ h7 a4 ]%%%%%%%%%%%%%%%%%%%%%%%! y! ?. {: W) c1 [
一、 遵守Performance Acceleration的规则
. G* u, e3 R% u: T9 K  v8 P. G' }0 a$ S
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将" k1 V# w& `8 v8 v6 x5 X
其规则总结如下7条:
9 x0 B/ D* B4 g9 m2 \  R  c1、只有使用以下数据类型,matlab才会对其加速:
4 A* W. b/ ^% X. z5 clogical,char,int8,uint8,int16,uint16,int32,uint32,double" O+ X1 d3 ?4 ^$ W% p1 m3 N! p
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
) d7 i/ Y6 ]) Q+ o* s* f/ Y4 n4 Ire,single,
2 ?9 G1 Z8 d: q6 {4 Y1 Q' i: H6 `5 \; x" q$ u# i: Z' O$ y
function handle,java classes,user classes,int64,uint64
# B" r6 B+ {6 |2、matlab不会对超过三维的数组进行加速。% z0 H3 D1 ?9 m# K7 H4 [# _) Y
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值! Y: ]9 o) d8 }5 C" K. q
来表示;- V# @/ J  h/ c$ x* F
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
0 O3 ^" T$ m: X% q7 d4 J1 `6 [6 m据类型,只使用
, J+ }) t' m8 Y. A9 O" @三维以下的数组;c、循环内只调用了内建函数(build-in function)。
! E) d+ F1 q" K- J8 E4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
; T" q( J( n8 m加速运行。  Z: ~1 o7 p+ J4 a2 K. o
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
1 j+ p+ H1 Y& s. K; h( q0 Vx = a.name; for k=1:10000, sin(A(k)), end;
4 e9 S! ^/ q8 y: K- d6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
. I9 D, Y2 Y& f# x度。
- N" m, @, c# g7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
  F' n  J" I, L( q/ d- j运行速度。
# g; `: m* ]  t8 ]! Q- M! c- l/ U4 A3 v
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/ X5 v4 j0 g7 [' L& y5 \
%%%%%%%%%%%%%%%%%%%%%%%, C5 Z- l. V% w5 h3 N
二、 遵守三条规则8 N  r3 @9 A1 g' R; r( K. E

$ [* H( D: r  ?# `& L; k* H" p! F1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic
4 e' x) w# O1 v2 a! ph means it is designed" _! v2 ]" ]5 d" }% x/ k/ C
% {4 s. T0 ^8 T" i; p* G. o# n" F
for vector and matrix operations. You can often speed up your M-file c
; E/ M/ R' d$ ^ode by using
; r' N) A# u; x7 e% f$ yvectorizing algorithms that take advantage of this design. Vectorizati2 e2 f- r5 ^- Q
on means converting$ R6 ^2 K7 Q5 H9 G8 w: j4 m% X
for and while loops to equivalent vector or matrix operations.”。改进
( w6 v$ G" P( _' Q, A3 x* Q这样的状况有两种方法:
. x- v7 F; [' h' t2 o0 O3 v; x2 i. [- {) V8 S0 P' I: }
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
+ u7 O7 {5 r! m
. [" j# i) P; G; R: ci=0;
) `" B2 p9 s& F: |" Dfor t = 0:.01:10) p1 k8 \8 D  _4 }: y. S9 ^. u" |3 V3 \
i = i+1;
0 g- K: k, Q9 }' R) my(i) = sin(t);
( h% `" a- Y& D5 l  Tend7 S. f8 U9 ]- E4 c9 d$ }& k
替换为:
' m3 L$ U: l0 U4 [1 A8 Y/ at = 0:.01:10;
' Y% H4 M+ N0 b6 v- Dy = sin(t);
# w% z9 ^; H7 X& f速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i# f( Y7 C/ T- g' G: n* h
permute、permute、" M3 `- v& P8 V5 A
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums
5 ]+ I- `. d" I; x" I) a: k4 sum、ind2sub、4 t, `# K6 K4 a7 I# u, a6 N2 h! B
ndgrid、repmat、sort、sum 等。
/ ?; S' z2 d) q% A0 e8 y+ e
# t# {% ^5 \8 R6 Q! F* F1 @8 r请注意matlan文档中还有这样一句补充:“Before taking the time to4 W6 Y. X8 L7 p0 _  x" E# g

' j& F: ~" a+ O  o0 mvectorize your code, read the section on Performance Acceleration.
+ i, N* N. A' Y, ?You may be able to
& _5 G1 }0 u; L# zspeed up your program by just as much using the MATLAB JIT Accelera# M3 z! H0 z3 h( {
tor instead of! [9 R, @6 t5 t! L$ [: F
vectorizing.”。何去何从,自己把握。
' u; \2 m" B9 r) G1 h0 c" F3 t- L4 z: J: ^
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执4 G& Z9 R9 T* W( \- E
行循环次数少的,
+ }, J: T' g& [6 Y: B8 |- D( c内环执行循环次数多的。这样可以显著提高速度。4 L" }  g% p1 O0 I0 A0 m7 R

5 q& v9 V( p' V$ g3 F( g0 [' t2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on- ~5 \( A$ a( j% \3 [
es、cell、struct、3 t! s7 f, @  H8 D! e+ `4 U& {
repmat等。
* I8 `; d( {/ v' R* Rb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
) J3 Q( y. n( |& k+ {
4 F  j# t5 T# z$ ~3 sA = int8(zeros(100));
$ [6 m! U# i0 H% u换成:8 |4 x3 l2 M* w. D. w0 x3 A
A = repmat(int8(0), 100, 100);
; B3 F  ~! A+ k" Ac、当需要扩充一个变量的大小、维数时使用repmat函数。
5 ~8 O3 g  ~- C% J$ h" M; C7 v3 S
5 y; H! I7 ]; _! I, O  x& `3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
$ z) `. u: c5 C: o7 fb、使用Functions而不是Scripts 。% J/ X) C# T0 b3 ]% j+ k4 E

$ q# v9 k& V9 q* w; o! f5 A8 m%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%+ Z  {: f# B4 o! w4 d7 Q
%%%%%%%%%%%%%%%%%%%%%%%
+ x  m9 u% v5 h4 V$ T/ W三、 绝招
7 y$ L3 j" j9 N( `/ ?3 F! l/ v
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。& J5 N" r$ I& i) I
1、改用更有效的算法
3 L+ f6 w9 K, P# e5 u2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
, r7 U& K- n5 G; m1 L; B7 }2 Y! {) ~: f$ s3 i# ]
关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
1 D% g( F! ~" B! F7 W1 k语言文件,VC编译




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5