- 在线时间
- 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
% ?& r( ?9 ]7 ]$ |- W标 题: 加速matlab运行的三重境界
& |& N% q! ?; v/ R0 x; H* ~+ F; o发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)
* w: w) b5 E! P) B9 q
: i0 n' R2 Y7 g加速matlab运行的三重境界
6 v1 ~' i; C3 J' C* X- ~- s) _, r
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' t6 V$ l, C1 `%%%%%%%%%%%%%%%%%%%%%%% V; u( [4 ~% g) Z& p2 p5 _5 D
一、 遵守Performance Acceleration的规则+ n u F9 p% c5 k4 ]
二、 遵守三条规则) _7 h- T5 y0 M
三、 绝招
0 t0 S7 E# [' j6 y) C& f' \. X- E$ t6 d6 }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%. h+ J4 m) \, z: \, m. F+ x
%%%%%%%%%%%%%%%%%%%%%%%# D5 z- D3 z$ T
一、 遵守Performance Acceleration的规则8 W* z9 \' ~/ M. D! t
5 l" _: ~4 d% `3 j$ [+ x* z `
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
/ r; S% w, q2 D其规则总结如下7条:
- Y- q' l9 o% g+ ?# N" }1、只有使用以下数据类型,matlab才会对其加速:
% V) C" S/ {( p- a; flogical,char,int8,uint8,int16,uint16,int32,uint32,double- o0 D- U* t7 m7 x
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
) e$ {3 b, j, yre,single,
$ O% P8 D0 t3 J" A2 u1 X1 F; J( d3 s W/ Q1 e( {
function handle,java classes,user classes,int64,uint64
4 ?( y) d7 D O2、matlab不会对超过三维的数组进行加速。1 w6 A8 S8 \: F6 i- M- t
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值, I' J, e! Z5 U7 ?+ V
来表示;0 I9 W3 w b% k8 [+ X5 {& Z1 d2 n, E' {
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数1 Q/ t* ~3 S1 s* I# ]8 I/ A
据类型,只使用
+ l0 r% j# f3 B三维以下的数组;c、循环内只调用了内建函数(build-in function)。! o9 S$ K, m# E, ^$ Y2 h4 G
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
* t5 a# p( _" W. T; D加速运行。
; w- C5 H, H5 I5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
3 D3 f" C9 ^) H; Q, tx = a.name; for k=1:10000, sin(A(k)), end;
3 P9 c; `& V# z! R3 T6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
# O: O1 j4 x4 p9 Z度。
0 T: M& `# {1 G+ C Q7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低! T5 p U0 G& j$ E! B! T; Z' Q
运行速度。
& p' ~! c+ ~2 @
# w. r5 B# y9 q/ M! G9 J. o%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 G2 X J* E- d, @
%%%%%%%%%%%%%%%%%%%%%%%; u3 m# m# n7 s. m7 f" i( h
二、 遵守三条规则; h' H3 j1 J7 y y$ ?3 I( w1 h8 J" V
7 i# w- ? J8 L6 i5 t, P
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic6 j% \4 j& Z8 n$ B) }
h means it is designed5 ]% z6 `. N! j% B5 A
q) z* y8 h" m. m% ?
for vector and matrix operations. You can often speed up your M-file c
. Y$ k- b6 h& d, _ode by using
9 K; ^: Y( T" `8 Pvectorizing algorithms that take advantage of this design. Vectorizati& ^6 H/ ]- [* ]' ~% j' k8 ^. \1 P
on means converting
* R% H! _+ j8 Hfor and while loops to equivalent vector or matrix operations.”。改进
' e; Z- V; C4 J. E$ {; _) Q6 n8 G+ W A这样的状况有两种方法:. @; J+ z) r. B
. M# l2 U3 E! ^/ Ua、尽量用向量化的运算来代替循环操作。如将下面的程序:
- b; _, q4 {% ~) p4 |
0 S8 Z* P( k8 A- Yi=0;
; c6 J* w; ~# R1 m+ X: O6 Cfor t = 0:.01:10( a; A( m- j( a% o
i = i+1;2 t' [; @1 i8 Z, K/ _
y(i) = sin(t);3 r$ J) t- ?# z, d( `
end9 U2 F9 i. ]& M( Z5 C! y
替换为:
% r# }/ h; ?0 N" p4 u% p+ k8 S, Rt = 0:.01:10;* h }% M/ j. o4 ?
y = sin(t);
4 U+ f1 N0 A" M' {; R速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i8 u' i! t4 ~+ ~
permute、permute、# m$ A# ]; o( o4 x( O
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums
/ t" j0 K+ F. ? x1 z; X+ Z# sum、ind2sub、
w5 _6 q, y! G# V# S* U0 w6 Nndgrid、repmat、sort、sum 等。
, q2 Y7 U6 a: J7 k& D& K
1 C5 b2 ^$ @/ L" X- `4 J! D请注意matlan文档中还有这样一句补充:“Before taking the time to
6 i& _& i, b+ y% Z( n! V7 N
" W3 X( d' O8 xvectorize your code, read the section on Performance Acceleration.
$ c; Z9 j% U! e+ c+ DYou may be able to5 h' M9 Q2 P) a" ]0 a
speed up your program by just as much using the MATLAB JIT Accelera: k( R4 w3 \5 w
tor instead of2 E5 @* X2 N. ?: X- F
vectorizing.”。何去何从,自己把握。
$ V K' U, E) x; x* b y
: _ x6 g! b6 V0 Z6 o, c* W& P0 ~b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执. h4 m9 I! w3 H/ C5 p% Q" l3 o& U
行循环次数少的,
, ^2 R: | x) p0 l5 T6 g; p& N内环执行循环次数多的。这样可以显著提高速度。
4 d |8 M$ G, s% Z4 D' C- t. y. ~) A, s5 F% A: h& v$ V
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
1 F+ G4 k/ e- P5 c9 J4 {es、cell、struct、- g, G. t9 Y& B; T& M
repmat等。7 ~3 }1 p( R2 ?* F' p8 x. A
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:/ g4 r* w. j# s/ L$ _7 u
2 K: Q! E" A8 Q' Y7 [% d! ]
A = int8(zeros(100));
* X' Z/ _7 s* C( g( J/ u换成:2 ^( l1 h! ~/ C
A = repmat(int8(0), 100, 100);
1 ], S- l9 s- |c、当需要扩充一个变量的大小、维数时使用repmat函数。+ \/ i' q* h0 p0 u8 y3 Q1 S
$ g) d9 J( f9 v' R) k% R( G
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
2 g, ]( M5 M" T+ Fb、使用Functions而不是Scripts 。
) S5 Q. M! e& x) a
5 M7 ~3 L- U6 W, {* v. e%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 A7 F* a0 _" n" J+ }4 F H- {# p%%%%%%%%%%%%%%%%%%%%%%%8 W+ H) v8 t# k! }
三、 绝招
Y* i8 y( Q: H$ L; V
o: x% Z: T' m) V7 q4 ~1 ?你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
4 r$ C# |. _: @; T5 ?( K0 [1、改用更有效的算法
/ \' _1 y- R& X2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
+ [3 c+ H. z& v3 c
. s. c2 a" I2 I9 R( S9 C, Y关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
' q6 a1 D3 _/ r6 j+ i& ]# d语言文件,VC编译 |
zan
|