- 在线时间
- 0 小时
- 最后登录
- 2007-11-12
- 注册时间
- 2004-12-24
- 听众数
- 2
- 收听数
- 0
- 能力
- 0 分
- 体力
- 2467 点
- 威望
- 0 点
- 阅读权限
- 50
- 积分
- 882
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 205
- 主题
- 206
- 精华
- 2
- 分享
- 0
- 好友
- 0
升级   70.5% 该用户从未签到
 |
信人: fork (撒哈拉沙漠的沙), 信区: Matlab5 I5 Y) a+ I5 Q" O; x
标 题: 加速matlab运行的三重境界+ t# Y0 e$ Y& c5 }: e" J& k
发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004); w( ? ]5 ^9 t
, h( L$ C8 L3 ?& E6 k; _" o' s
加速matlab运行的三重境界
( j4 k* q% X+ N9 _: |
4 ^% y) ` C; Y! r Q* o; N: \%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%! s, D5 Y ?1 ~+ o, X
%%%%%%%%%%%%%%%%%%%%%%%8 R7 a3 w4 ^" G, h: D
一、 遵守Performance Acceleration的规则
3 \: Q E' C* C6 _二、 遵守三条规则
: U+ @6 a) p" n2 O( w8 Y( [: K$ p3 {三、 绝招
. y( q" T4 k- q& J. q; h. N
! o" m3 d, b! ]2 G0 H% S5 H%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%7 N" C$ N9 f) j8 z H2 W' Y
%%%%%%%%%%%%%%%%%%%%%%%
/ H( Y# T1 D) m7 ~一、 遵守Performance Acceleration的规则% C1 e' O0 @0 M# w
- B% C% z% o% }0 y6 M3 U关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
6 t1 ?4 [5 i3 J2 r其规则总结如下7条: M- J# I1 I8 u8 x# q
1、只有使用以下数据类型,matlab才会对其加速:- ^% E6 j2 d7 o3 w# M
logical,char,int8,uint8,int16,uint16,int32,uint32,double
" ], b5 _3 ^/ V8 H& g而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
$ ?" x: q. R+ V0 Q1 g. T- J# ire,single," S1 c+ C" _! S' G0 g* j$ n/ C" D6 ~
0 P8 A& o, H; X. J
function handle,java classes,user classes,int64,uint64
l, f# }! s' T, k( y0 Q) U2、matlab不会对超过三维的数组进行加速。
9 W# Q# H8 \- R3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
r* z+ t m4 V" G来表示;. Y; I8 R+ e- ~6 _6 \( j) Q) }0 J
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
, k+ t5 ]. j. B0 V" ]据类型,只使用7 k: z# I3 `# Q y; a7 x" @
三维以下的数组;c、循环内只调用了内建函数(build-in function)。7 I3 \0 q! _8 z$ L' c/ h
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将) c+ ?" ^! D8 F4 J- m( B. E- m
加速运行。
1 m) p* S7 L# E' b* r5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
" W3 M" c5 W5 W* H$ ix = a.name; for k=1:10000, sin(A(k)), end;' i, x# _+ N: y9 ~$ r! F8 |
6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
" G) Z, |2 G) q( b v: q度。
`+ L2 @4 |. Y* r% r3 u8 _7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低6 Z# w" n8 H! \7 N; Y* p) c: ^- G) w
运行速度。
4 A2 o) m5 s& X7 I" A$ L6 y( u4 v
; n6 v/ h9 n& q( G; I7 Z%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- M" s( e# h2 V4 M7 W* I%%%%%%%%%%%%%%%%%%%%%%%
0 c: w7 R1 X7 @2 M) p; W二、 遵守三条规则, r( s! t! L$ h
9 e" p: E. ~. O6 W, S" T x+ i1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic
* b8 f! _- P. l% @8 Q9 ah means it is designed
* |- j3 ]- ^+ U" ?9 {" T
6 ~, x2 a+ S; D# D, Kfor vector and matrix operations. You can often speed up your M-file c! v$ m- |! i, ] z! r+ m$ B
ode by using
0 F& X! }* |- ?# q, a2 Zvectorizing algorithms that take advantage of this design. Vectorizati
4 l) `: i, L9 f: i* H) ?on means converting
6 R- a: g& @0 {6 e- ufor and while loops to equivalent vector or matrix operations.”。改进
0 C" I; y+ |, s n! f* p这样的状况有两种方法:
6 f% ^6 I+ q1 f7 k# d4 M) ?& j K- x2 b; w
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
4 O* P8 _+ P4 ]2 j
! ?' H7 v- O3 b0 ^0 F: `i=0;
! \& P+ V1 A/ ^: g9 M9 Jfor t = 0:.01:10; M7 V. H8 w6 l" q6 m- C
i = i+1;# v1 C/ W9 u; }. H
y(i) = sin(t);
/ @5 ^, a5 j- X" t2 {end3 p$ U: {; r% Z
替换为:
y |) B% {- s: v* @" H. P# G, Y6 ?t = 0:.01:10;
' L. E+ o: u) c6 d+ e+ Dy = sin(t);# G2 F: D) |5 P4 k1 ~1 `" p
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i2 v! _4 _! a0 B, ]! w. g' D
permute、permute、
9 c. b$ ?% H- {reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums
; E$ D* q# O& ]4 wum、ind2sub、0 l1 u" q7 ^( d) Q
ndgrid、repmat、sort、sum 等。6 ^' X& |- c( h0 g' z9 }
5 A7 b. N/ n( I
请注意matlan文档中还有这样一句补充:“Before taking the time to* U5 n( z* w+ ^, A( z. T# h
: B& V' ]+ E6 B. v5 Q
vectorize your code, read the section on Performance Acceleration.
, i5 E0 P/ O+ @) N* W7 N0 M- M) J/ K$ IYou may be able to, v/ p; }' P* _* V+ q+ g( O
speed up your program by just as much using the MATLAB JIT Accelera
' g$ ~6 T" k) X, utor instead of
! S5 X0 c, x0 U8 ]( Rvectorizing.”。何去何从,自己把握。7 _3 r: x8 w/ j% y4 n6 B& c
8 J; h" n6 g8 K1 j/ Eb、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执* q1 r3 r5 T M
行循环次数少的,6 @% f1 k8 H! e
内环执行循环次数多的。这样可以显著提高速度。" L! B2 p6 `5 t7 f! Z0 f2 _* Y
! w, [5 D2 S; o& e- P- T" T6 }
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on d9 e. c4 s2 x0 U: O
es、cell、struct、" ?, S8 R& a- E
repmat等。
- x7 j+ ]7 x2 D4 L" ]0 yb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
4 Z1 ^3 U2 b# M3 ^
5 _ C" A5 \; S2 E' e0 YA = int8(zeros(100));6 g7 C' \! n9 t, z. |, G. a
换成:
3 @8 y* S+ i2 WA = repmat(int8(0), 100, 100);9 v2 e2 @" L' l. y$ g$ F
c、当需要扩充一个变量的大小、维数时使用repmat函数。4 b7 h8 u* A: B" E. D' ~
2 W4 Y2 R. s' P
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
1 ?" g2 {3 [2 k$ J% \$ H8 pb、使用Functions而不是Scripts 。
2 |( j E6 }/ N* c" i2 A5 G' m! _, r/ a
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%) {; y: G' a& J0 @7 U; t
%%%%%%%%%%%%%%%%%%%%%%%
4 b9 t' o- p! I" \三、 绝招
8 S# G: t4 S% O, a8 X O# e: y+ k( K: j( l% x, _4 A3 t% t0 b1 [
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
) ^: P0 j C7 c1、改用更有效的算法2 o! K+ p7 l3 g4 }+ _
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。% J( l ]8 T& C) e& L. t+ f( h
; J7 t, S8 W4 c" N+ u! w关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
/ ~0 ^) J+ V- q9 X8 e8 _; w: w语言文件,VC编译 |
zan
|