- 在线时间
- 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 b3 \7 b0 o2 ~! A9 ]8 F
标 题: 加速matlab运行的三重境界
8 [% x* d3 z/ I7 n5 |3 D( d2 ^: a发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004) z! }; E2 }9 n: j0 R
2 [; k: O1 O& e% K& o3 M6 Q3 i
加速matlab运行的三重境界
2 s! S/ b: E j: @, s6 U! d( b
; Z! ~5 Z8 m! X6 u%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
) ?" E4 l" a) M. {%%%%%%%%%%%%%%%%%%%%%%%
& Y- e) j* z0 J1 l一、 遵守Performance Acceleration的规则( D! V3 m& A6 T
二、 遵守三条规则
' U" j; y: r: F. V$ Q$ U三、 绝招
6 V- \$ m( S- L
# h- D0 K& O! d1 N! p! [$ G/ ~. ~9 x%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% R" u) ]3 Q: t5 q
%%%%%%%%%%%%%%%%%%%%%%%& m0 Y7 _/ @7 k; K0 w6 i$ l
一、 遵守Performance Acceleration的规则
) }9 p* {2 e5 s" E/ E3 G# ]" U+ E
/ ]# N2 _' c9 y5 b! Q$ R4 V关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
5 v% D: s1 k, S- X其规则总结如下7条:
8 |8 I2 ?' U: c; I: `4 P1、只有使用以下数据类型,matlab才会对其加速:, R" v3 [7 o) O c! F
logical,char,int8,uint8,int16,uint16,int32,uint32,double
* f8 ]9 s- a6 X( \; r2 F' X而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
+ {% n! O2 W6 v/ b0 h! |1 Y2 _re,single,
. Y* ?4 a/ f, ?9 V* q* Z; b) K p0 s' U h3 x
function handle,java classes,user classes,int64,uint64
4 A: N" p: H' g2、matlab不会对超过三维的数组进行加速。% D- E9 ^5 s" t# N" |; z" i2 j% o# f
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
% e. v( o' D# @来表示;
+ A( b* q1 g' a( L) E% |9 w; vb、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数% ?0 l2 Z0 F: s x D I9 n
据类型,只使用1 X; n5 O* V5 h8 I5 z
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
/ v. ?% @2 ?5 x0 x4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
: S e: G# q; f/ i% \( D加速运行。
+ C5 z( M$ V- X. U5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:' \8 m$ ]5 t$ z
x = a.name; for k=1:10000, sin(A(k)), end;
, i( f1 m* ]! Q' P: O* s6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速" k) g% y9 y! R( z( r
度。: M1 b( Z5 w$ T/ v+ f& J" r2 Z$ x
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
6 ]6 B7 c G/ s. F: W运行速度。2 A) c7 j' X1 f! P3 ?( U* p) y
U' R4 S5 J% C
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1 J8 q/ R5 Q- p( S$ H; |4 ]( w' s! |- V%%%%%%%%%%%%%%%%%%%%%%%0 ~( d* j: c3 M) o8 V( p
二、 遵守三条规则( @" w- N) K) d! U6 y% U( A
5 \1 ~8 |. l2 Y( r6 S. }! C8 W
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic
7 g. m# R# n+ w* Q9 E' K5 ?; Xh means it is designed
( ?6 ^! k3 P( ]+ ]/ J, \; z% l0 J3 X" g. A5 g
for vector and matrix operations. You can often speed up your M-file c0 B6 e. }% m( p6 {+ T
ode by using: c7 Z" b) R( j: I+ [
vectorizing algorithms that take advantage of this design. Vectorizati$ ^5 n0 T0 H1 d, |1 H, r
on means converting
4 g5 M; I# i) p. Jfor and while loops to equivalent vector or matrix operations.”。改进8 l0 x; c8 W2 ?% w6 j' E% g M
这样的状况有两种方法:( c3 f+ q1 Q; G' m4 h$ s9 T7 Z" r
- ?- q0 P: B* H4 R5 s1 N
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
8 d6 D8 l# L2 S% M/ M! W% |% P# B- v7 c9 Z# m6 w# J+ U8 r; c
i=0;, d) `5 w' B& p1 v* [4 R% C6 h
for t = 0:.01:108 T4 U6 A; p" y7 C( x" ?* g
i = i+1;: p* p$ k) R1 @1 V
y(i) = sin(t);. Q: \/ q$ a- ^# R+ s6 g2 j0 N
end& X, Q3 J- I% k" x' R1 |# z, ~% y
替换为:
% `) L6 D9 o/ r7 _+ y: Y+ G8 e( ^t = 0:.01:10;( R/ f0 @- q5 P" d$ R; c4 ^. e) E
y = sin(t);, r7 ?1 n' j' ]$ k* O
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i! g K. K1 o# c. m$ p
permute、permute、
- ?' f2 T- X1 s9 U+ Qreshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums! A5 {1 e! O8 Z; x
um、ind2sub、
2 r) `2 V* n _, G5 |" cndgrid、repmat、sort、sum 等。6 n% g7 D1 B7 n% \5 p
/ t) i7 Z/ }) T5 E" t# S
请注意matlan文档中还有这样一句补充:“Before taking the time to, K0 N+ E$ _' a. l, {3 Z8 o" h3 i+ l
: v. C" z; y8 q8 P2 avectorize your code, read the section on Performance Acceleration.* E% {+ M5 F# A# |& B" B+ p2 x
You may be able to; k9 \4 |/ `0 V2 \! c
speed up your program by just as much using the MATLAB JIT Accelera
4 G, g. C' v# l" ctor instead of
: h2 }: d) ?( F7 I! j- yvectorizing.”。何去何从,自己把握。
- a% {. T5 e" G3 W1 J: g- \7 }9 A4 `8 ~' ?
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
$ ]$ R" c9 U6 H m- O D行循环次数少的,
! Z$ s" o! S0 N6 Z内环执行循环次数多的。这样可以显著提高速度。
2 [4 V! p4 N) v, z0 x- X9 P) o1 P8 P( X7 l$ d" z. y
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
/ }% I( _' s3 W$ P, A1 p; X0 [es、cell、struct、# D9 ^- Y; j. s7 I4 a. `
repmat等。
9 Q$ @$ q4 g. H5 B) |" xb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:/ _8 s; [. a! ^, w: a/ J! l
5 v' n: W/ i8 N; b! N' k
A = int8(zeros(100));
% \ E) f: k7 P换成:
6 |! W: B8 W# _6 l7 Y& EA = repmat(int8(0), 100, 100);
5 `* R0 E! j- P8 {$ }/ Bc、当需要扩充一个变量的大小、维数时使用repmat函数。- f# ^) C! G+ u7 n. K
4 e- |0 r/ J; C+ D3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
% V ?" ~9 ^; a8 c. x( Sb、使用Functions而不是Scripts 。
7 V& \- n' L* R0 n% ^
2 P$ j6 S( L- }/ _2 m%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%6 D5 H5 {. d7 H8 |# p3 ~! ~
%%%%%%%%%%%%%%%%%%%%%%%) [& S; p' Q1 ]. y% N
三、 绝招
. E, a, S; g" W1 v
; s5 H# _1 S1 d) A6 c& z. Z& G你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。% m. |6 P3 v* r v3 Y' J0 h7 ?& L* I
1、改用更有效的算法
+ X2 m* ~# x! k" ~2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。7 I7 |& b, e; F) n9 p! l
9 J3 D& ]( T' X6 {$ U! ^# Q5 Q! e" r
关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
! K+ p+ F5 O8 m6 q% Z语言文件,VC编译 |
zan
|