- 在线时间
- 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 (撒哈拉沙漠的沙), 信区: Matlab8 Z& }8 F" d( d1 T5 p) B# {: ]
标 题: 加速matlab运行的三重境界/ M1 O" c; h; f2 U3 V
发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004): T3 N$ \2 ^' N* U
! P2 A* J& E2 t: {
加速matlab运行的三重境界/ Q1 S$ S; k" S# b+ f
3 {' A! X q7 s i' |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%' }7 c: o5 j, o6 ]
%%%%%%%%%%%%%%%%%%%%%%%# [% |" v: D) V3 w! X) ~. ]& K
一、 遵守Performance Acceleration的规则
/ x8 I0 O' v9 i4 Q2 r5 @二、 遵守三条规则
0 j8 h2 ~+ F, @* g) L三、 绝招: b7 y! S9 q+ \ W
- }9 j/ ]% n O6 l9 I%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% G- J9 S8 b; d! j' [4 @* K. S%%%%%%%%%%%%%%%%%%%%%%%" g. b" o1 H0 @' p- e: I
一、 遵守Performance Acceleration的规则# q0 N* v/ j$ x Y' S! I' }$ b8 U
+ I5 ?, S! i% P* g4 b) s关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
' w V* X5 h1 N C0 [" Q+ D其规则总结如下7条:
" ]$ t2 B' W% o, J2 V7 Q1、只有使用以下数据类型,matlab才会对其加速:5 ~# R" B% K% a/ p" t: E5 K
logical,char,int8,uint8,int16,uint16,int32,uint32,double
( F- ?6 n$ X5 s) s" S+ _$ [而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
9 e/ a4 s! t( P' `1 i1 Kre,single,( ~; f) P; L: [3 T4 H; g1 `/ U
0 c3 k1 R7 }; j. ^5 q- U" u1 pfunction handle,java classes,user classes,int64,uint641 G/ ^1 G6 M$ _* Y
2、matlab不会对超过三维的数组进行加速。
. A+ L/ v4 i6 a7 j5 u; j% W; R3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
. [: F2 O) c+ k) ]1 _' s/ G7 T来表示;
- a( e. G8 @# I" c$ g% i* kb、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
! S' a+ B8 b0 w( f% W据类型,只使用( W7 J# y" ^+ V! p
三维以下的数组;c、循环内只调用了内建函数(build-in function)。3 t: N: c0 J0 [; x, u) }. A
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将8 C* q7 _( B1 ~) S8 @0 o9 I
加速运行。! o8 f2 r4 P3 W6 u8 f
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:- |- ~) P T/ I0 ]! m' ~
x = a.name; for k=1:10000, sin(A(k)), end;
- r$ _) V! J0 {" u6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
$ d A/ Z8 l3 C, J$ s度。- c& ~& T. n7 i; n9 v$ F; n- C
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
( t, n3 {4 O) G运行速度。- R- |+ J8 i" I$ b
0 w" n z7 A: Y3 I2 u( k
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9 X: C! v' a6 ~- p. |%%%%%%%%%%%%%%%%%%%%%%%
4 o. }! W' `7 w `+ l5 O$ `二、 遵守三条规则7 [4 e1 [7 o! ]' [4 R/ E
3 p) m" S" d# c& z5 ?* l) L1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic* `& F9 y I8 ?2 a
h means it is designed
3 b$ u+ G' {5 u/ @/ K d2 r4 c( p, r3 a$ ^ b) d
for vector and matrix operations. You can often speed up your M-file c
5 x* Y( Y+ B# Yode by using3 V( a; p I2 H8 s& E$ k. s
vectorizing algorithms that take advantage of this design. Vectorizati% Q: q, A+ F- l9 N
on means converting
/ `/ N$ j- L1 C' ?: @for and while loops to equivalent vector or matrix operations.”。改进
8 R/ o* T6 B3 g2 A! J7 B这样的状况有两种方法:9 [' Z h# ?8 {/ W& M/ \
) A( r: o( W& W: b+ C
a、尽量用向量化的运算来代替循环操作。如将下面的程序:* k/ ]6 O6 o' a+ R
+ \9 o5 l& X" O
i=0;% L$ p6 l5 l; ^$ f7 P: s( J
for t = 0:.01:10' P4 q8 X x& `& G& e4 D7 `2 p
i = i+1;
7 \" x3 P) m6 W% |) f/ S! |y(i) = sin(t);
/ \" L6 p, X. y j2 Jend, E4 X0 D, W. p7 @) _2 }
替换为:
$ [1 g# }* i2 ^) S* st = 0:.01:10;" M7 z( j* x9 |8 {
y = sin(t);4 b+ U. ?' ?, |
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i: l8 `2 K/ f2 \: G0 M" x: _% o. V
permute、permute、 Q3 m% Z2 F Q; d: @
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums
$ v* K) x: l6 d# b! \, K. g, }um、ind2sub、
' H; s0 S" }, j! z9 y5 Yndgrid、repmat、sort、sum 等。
u9 p3 r' x! L8 U: o% v% z# R0 j- ~. |! J
请注意matlan文档中还有这样一句补充:“Before taking the time to# E: o9 H8 V( J0 N: A4 a% [1 N
y% t0 Y% d2 s1 h, A1 gvectorize your code, read the section on Performance Acceleration.
$ d9 Z: f, ^2 }" qYou may be able to6 J/ M. v; \3 y; ?* x
speed up your program by just as much using the MATLAB JIT Accelera1 }& |( b. d# W8 U- v
tor instead of" v( Z' q3 H9 _- ?
vectorizing.”。何去何从,自己把握。/ S0 \3 q# e/ f; [- X5 k
8 I9 j' ^1 T# v. s; _# L
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
$ g8 L. p; @# W7 S3 [+ Y" A行循环次数少的, q% Z& C7 o( h; c% n, q! D
内环执行循环次数多的。这样可以显著提高速度。
8 s" u) a3 B& @: D2 c, M* b/ \9 s( p, O; q3 z0 t
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on" }7 R! n6 f6 t$ U: s% S
es、cell、struct、
0 h) I. W& f) H* \/ e7 yrepmat等。3 G- p: r; O! {' |
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
8 x0 ?8 {% D x; I" c% ~- h) W' K- Z. w' h$ t
A = int8(zeros(100));
# |: A3 G X# A0 Y换成:# ] b- b6 a3 w; e# c
A = repmat(int8(0), 100, 100);
/ {2 j: k) W* `' C! c( Lc、当需要扩充一个变量的大小、维数时使用repmat函数。7 A1 C7 v! Z; U0 h! c
' X/ F; ^' J$ e+ W: n9 \
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。6 K1 H$ B6 t$ P O4 q% {) t; i/ V
b、使用Functions而不是Scripts 。
, i; f/ x; x- v. U2 z
( c0 q Y" g D# g5 `% E%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%- V3 w7 r* W2 Y I: r
%%%%%%%%%%%%%%%%%%%%%%%2 R% ^0 F2 }8 P
三、 绝招" Y- `+ X* P# Q3 }
5 K, j9 a+ g- W7 M
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
?9 w% X& t( Y. G- g# M& f! S) }1、改用更有效的算法- n* K: M2 O6 [! f8 C( l
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
, d# A. f4 a }7 S/ J1 g% n, L/ A
; I: [6 t3 q# Y1 Z5 y9 n关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
: S n$ p) A+ F: X( f9 q语言文件,VC编译 |
zan
|