- 在线时间
- 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 (撒哈拉沙漠的沙), 信区: Matlab
- {) ]1 `. D0 i8 M标 题: 加速matlab运行的三重境界
9 g5 \5 \; L6 R" N" K \* z发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004), i5 L2 @' I: D/ M6 D
* ]3 z! y/ Z' z. D2 D
加速matlab运行的三重境界" h. U- ]: V2 _' Y8 U
, x1 U- |- r( X G
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%. d0 H3 U5 G) X3 Z1 F' j
%%%%%%%%%%%%%%%%%%%%%%%
3 i0 @1 w6 J* }( ~# Y一、 遵守Performance Acceleration的规则3 s! q5 F: t0 H8 L
二、 遵守三条规则
$ R; n/ w* d/ ]4 t三、 绝招
9 e6 P7 x: |; x% Q- E) `; k7 J; J8 `$ F9 M
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$ e4 X4 @4 N% A, v$ F+ ]
%%%%%%%%%%%%%%%%%%%%%%% X, O/ J1 E/ a0 _5 K. K
一、 遵守Performance Acceleration的规则
5 V g0 L2 a+ o& [& i, d, l, W) Y- L0 j
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将 k* _3 a' f7 q. A( h0 u' w
其规则总结如下7条:
& k% {0 ~0 c) e1、只有使用以下数据类型,matlab才会对其加速:
! {) w2 Z) ?( |: I1 ]% w% Ological,char,int8,uint8,int16,uint16,int32,uint32,double; H# F( ]$ j; t; @6 F1 k" J
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
5 q, I: a( p r3 O8 G7 jre,single,
R9 v* m: a9 z% b; X# a: }, @" V5 G6 M
function handle,java classes,user classes,int64,uint64
# z1 m4 R6 q! w) L5 {% G2、matlab不会对超过三维的数组进行加速。 g* I# ?1 |- ^8 v5 g2 B, a$ u
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
2 T% ^* Q+ g- i7 W. r3 r( B来表示;: z4 N6 X- ^3 w5 {/ M! h {
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
' Y T( d6 [; ~据类型,只使用 K4 t5 J1 p7 f0 y8 k
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
1 W: w8 N- D8 R- ], A; Y& T4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将 i7 b6 n& E9 n' ~6 e
加速运行。
4 v: h+ z% O8 F m1 `5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
" p \2 n( S4 ^ Z+ dx = a.name; for k=1:10000, sin(A(k)), end;
7 H6 ? [* K. G# K# E& s+ |8 a* y! O8 b6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
! D2 X) J% g: e2 i. d- f. n+ {度。0 I/ t% f# {$ G, Y/ Z( h& b
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
2 P. Y0 ~: L& c% B' f运行速度。
$ t# i4 b a! d6 ^/ {$ F3 q u3 S" r, ]0 g
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%, g0 f, D. `3 F( k' l, x u, o! d; V
%%%%%%%%%%%%%%%%%%%%%%%
1 Q( c1 @1 q8 j \二、 遵守三条规则) Q1 @: R$ E, r) i
G6 r( @) x" V( U8 K6 w# h7 v
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic. ?" n( `- ~! `& `7 W% D
h means it is designed) ~0 j& ]2 n8 X+ @
; K0 w9 _! T5 p7 T3 {
for vector and matrix operations. You can often speed up your M-file c/ b% e. O$ y, {! ~4 z' \# S4 W
ode by using
7 H" J# Q3 B4 c$ M! Q1 O" T# Evectorizing algorithms that take advantage of this design. Vectorizati
8 [* G' W K! o3 ^$ qon means converting
2 n2 \7 U, V5 ~ q9 l+ afor and while loops to equivalent vector or matrix operations.”。改进
9 Q: p: a% @4 D% K/ o" W, h. K这样的状况有两种方法:0 a1 J/ ]( {- m( b. d9 q
' g: e" d# p) Y. T1 j
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
5 i' R8 t' D, F1 H @( D. f6 M. c& Z4 Z. p
i=0;* D; J6 M9 s) w& }' X/ w9 ]7 n( n- c
for t = 0:.01:10' }4 U5 c- k: w. a3 z
i = i+1;
, l3 n5 C' J! j* ?. [y(i) = sin(t);, u" Q* j) a" }: ?& T) C
end
$ x" ?; c# O$ t, R i! ?# p# E替换为:% _4 v8 W/ b! x; m$ G0 k+ m
t = 0:.01:10;7 }1 E/ c" ~4 M- o, L
y = sin(t);' j0 f8 L' R( N3 a2 ]6 z5 |$ b
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i4 _5 C, I# \8 m+ ?5 N+ e7 P7 J& ~
permute、permute、
& w$ V) T' i( q O& treshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums5 G( G" C1 d% a: F6 t+ G1 X
um、ind2sub、
- P/ p! i5 T/ [ Hndgrid、repmat、sort、sum 等。
' g G- s- T) c: [- Q8 O K% W* \
: n; @, p! ]* p0 F请注意matlan文档中还有这样一句补充:“Before taking the time to
u7 H1 e9 @- y E
" G! |* R( x* {- `) P% `8 Rvectorize your code, read the section on Performance Acceleration.
/ Y4 Q1 \& N) D5 k9 e, [+ ^4 DYou may be able to3 [3 d! H7 g' R& ?* n; N
speed up your program by just as much using the MATLAB JIT Accelera
8 Q: ~( ~# A5 i2 s. ztor instead of) m# {+ k* [% c x- d1 P
vectorizing.”。何去何从,自己把握。
- i: y) E+ p* S- e: a* d7 C, [$ F( U) ]
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
! z* F' E/ }; w0 U3 I行循环次数少的,0 Z1 x/ l8 g4 l) z3 K# I0 D
内环执行循环次数多的。这样可以显著提高速度。
* j& @0 Z; I" U% N; v7 K0 N( z
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on9 p- {5 y5 Q7 i, @' l! f
es、cell、struct、
# x4 n4 H, W5 j" q% S9 nrepmat等。5 j& ^9 T, Q8 [4 A, `8 }
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
7 i5 ~: b! q1 ^; {' Z
) d* J2 ?, l# o. U0 _9 eA = int8(zeros(100));
) [1 G" b1 @ s2 _% _0 G换成:
z9 V, e- Y3 J: W' N/ _' x' fA = repmat(int8(0), 100, 100);
8 ~* ~. i" ?0 i0 ]% s+ k: lc、当需要扩充一个变量的大小、维数时使用repmat函数。6 x3 N; v7 b& L9 c
1 r, v& Z% U+ o; S7 Y3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
, G1 o7 U1 J' I9 wb、使用Functions而不是Scripts 。7 h6 T4 F7 n5 }5 o
: Q- j: N; j/ P* |% Y7 U5 \4 q3 X
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%2 J4 |$ p% `2 A, v x. z8 X
%%%%%%%%%%%%%%%%%%%%%%%# E4 |0 |, [/ I' f: I! f
三、 绝招5 _. P% |9 p# w
, L, g O4 S2 }0 m
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
) r$ ^3 T; H" V; W) L: {1、改用更有效的算法1 {6 j: X% y7 P1 x2 E( N
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
$ q0 x5 E3 K) l' C6 ?% v8 F% g& ]. Y" p- t, X
关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
" I7 B+ d5 E+ C7 ~" U8 l, T! W语言文件,VC编译 |
zan
|