- 在线时间
- 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$ W) @+ \; P: W+ q标 题: 加速matlab运行的三重境界
/ Z) J6 c- q8 e3 w4 l发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)" G0 r* y0 L! J7 \, e
! N- B# I+ v5 f, \& ]' x加速matlab运行的三重境界* D8 J0 w9 h6 ]# Z& f$ K
, {4 H6 Z) B) { d# a
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%& F9 k! ?8 |' W1 J0 U
%%%%%%%%%%%%%%%%%%%%%%%; ? I. X3 ? E' N/ j% N! D
一、 遵守Performance Acceleration的规则
( n# t) S( s/ w二、 遵守三条规则
" c1 D4 ]$ q: N' N( H% h三、 绝招
6 o. Q/ d/ f }$ i8 l
& j% W2 I- y/ T2 o0 }& N! g4 t9 _%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%# n# _2 h5 O" G( Z) s9 U0 n
%%%%%%%%%%%%%%%%%%%%%%%! \ a3 j @8 T. ]8 k6 V5 `% w* O
一、 遵守Performance Acceleration的规则0 m( A4 E. e' U5 S! F: E9 R
5 `% i# M; i4 g7 I
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
: e, v9 A6 X0 F; _. g2 ]+ O其规则总结如下7条:
2 t* ~- O F9 A/ L) d- C1、只有使用以下数据类型,matlab才会对其加速:+ X7 H) m/ Q5 {4 \: Q
logical,char,int8,uint8,int16,uint16,int32,uint32,double
8 r$ f! h% f- \! U5 o: a" n而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu2 t8 M5 P5 a4 Q+ H$ x
re,single,
+ C( E- U/ U, j- R' Y" {: Z" l
. k3 W6 l2 N9 A4 b6 n7 ~ o& a. pfunction handle,java classes,user classes,int64,uint64
# [: N8 `4 e& J# h. t, J2、matlab不会对超过三维的数组进行加速。9 h4 T& X/ H* w- ?, b
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
2 x1 p5 q# y# F0 K来表示;
" s) }' J5 L( E7 m5 Xb、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数7 \5 p+ S. M) S, ~. P
据类型,只使用% z5 B( R) T( m
三维以下的数组;c、循环内只调用了内建函数(build-in function)。5 V1 [- J" r7 s0 L
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将" O5 d5 b3 C; m6 u! `# }
加速运行。
* {% E$ h; O% A& M5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:. K. u3 u" T9 U
x = a.name; for k=1:10000, sin(A(k)), end;! O; {1 W% d. q8 [& p+ m( l8 t
6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速7 p2 O! a6 ~* N' w
度。& Y( _) O+ \! ~; B1 \
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低( N7 m/ e- }+ N
运行速度。* \% s4 F3 A0 h
7 {0 Q. f0 |/ D; c6 v, O
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1 _ k( j9 p% ^- G%%%%%%%%%%%%%%%%%%%%%%%
0 z" j; P! h9 ~8 D$ m( ?( R2 t( O二、 遵守三条规则
0 L! x" G0 D1 v) C8 r# N, r5 c# B7 K7 l4 j
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic$ i3 Q$ Z* i' ]1 | F
h means it is designed0 _' Z! w& C' Q& s w; g! v
- R6 R9 F7 V7 K8 ~5 m& Gfor vector and matrix operations. You can often speed up your M-file c1 e9 K, {7 h) `+ n5 R- V- m- U
ode by using
7 b$ I8 s9 m" A0 ^9 kvectorizing algorithms that take advantage of this design. Vectorizati
! E5 d) l( k; G5 T8 D& non means converting
+ }; J3 T4 ] \& j( b& w! e/ T+ \for and while loops to equivalent vector or matrix operations.”。改进
7 {8 p- @) U7 ^. y1 l* z这样的状况有两种方法:
2 N9 ~+ l/ B2 L
1 M4 B; L: W% ]; |8 q S( Pa、尽量用向量化的运算来代替循环操作。如将下面的程序:9 N5 f% Y- ]& M7 r7 w- h V
8 y8 u" j! }7 | v( K5 T2 m2 wi=0;# {' [6 a1 [2 h! d I# R! _* X
for t = 0:.01:10
B) \1 |" d) ^1 hi = i+1;5 l* R. L" w V! n+ ]4 A
y(i) = sin(t);' |, i |0 v G/ h3 K+ Y
end
" p7 R/ R6 r/ c+ O$ Y+ ]* Y) r |替换为:
5 N; \8 X& e5 U. v* \9 H) m) ]5 Jt = 0:.01:10;
( A) e, p) P- _* F, K$ ny = sin(t);$ u* E1 l7 Q. C7 w, s
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i' Z) h; q9 {" @% t1 x- |
permute、permute、
8 [6 V2 s ~) g- M, b# V+ qreshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums
& m; m5 w# k" P7 c8 T9 T, u* pum、ind2sub、
/ U! k+ A! U* r! a& P6 u% \ndgrid、repmat、sort、sum 等。2 e' S9 W$ _, O% d+ a+ L' M! [9 \
& Q# p% B* ~) v" Q* a1 _请注意matlan文档中还有这样一句补充:“Before taking the time to
1 W! ]5 a( X2 ]7 \( u$ r) `8 G& Q+ v0 n) R/ f" n
vectorize your code, read the section on Performance Acceleration.0 h; ], f" L; b
You may be able to
' j% d8 N W. m3 k( S% Ispeed up your program by just as much using the MATLAB JIT Accelera
5 U. [( T: e+ D( ^7 s; Ctor instead of
9 l8 Q% }3 T: f+ u0 S/ M0 p- V) |, e% Zvectorizing.”。何去何从,自己把握。
/ f$ Z1 P8 L$ l4 Q9 Q$ ^1 e! A4 y( D8 ~
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
4 b W/ ?) O% P行循环次数少的,2 S" O" s/ e* S" [
内环执行循环次数多的。这样可以显著提高速度。+ @1 u+ ]9 e1 H
8 a, U0 ~; ?5 n+ g# }+ D
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
7 f. A5 @6 ]; O+ [( ges、cell、struct、
) U% T# T, m2 X8 q% R/ |3 T* @repmat等。# M# u2 C# ]! o
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
" J. z. P+ m4 F
8 Q/ b+ v+ M- ~6 \8 QA = int8(zeros(100));( i# w# c& ]+ w/ r+ p; R4 F8 J
换成:
9 g* V. r$ K. a" U' j! j2 KA = repmat(int8(0), 100, 100);
- [- \2 ?9 @- H# X. c) O0 S, q- Zc、当需要扩充一个变量的大小、维数时使用repmat函数。$ v' l1 P# C2 K D- X$ W; w
& R3 s$ y' [. _( J7 d {7 q
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
) L( n! s* E5 c) F# n0 Gb、使用Functions而不是Scripts 。
- ]8 [+ O3 w8 d" J3 E8 A% h; V$ }3 V, L
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%7 _& B3 e7 K0 g3 \
%%%%%%%%%%%%%%%%%%%%%%% `7 y* g- d4 `/ g, m0 V
三、 绝招
5 `3 L* {, z4 i* y) @2 p/ Y5 [) v
2 R1 E6 Q, W) ^' @, O7 L2 A你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
2 \" j& j; V0 g! P7 R7 j1、改用更有效的算法) z& z( Z g4 m: P' ~
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
! W6 C {" u! w' h9 i
' T1 g W9 Q+ X8 |: e, b关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++) I6 N8 P) W, q& a6 J
语言文件,VC编译 |
zan
|