- 在线时间
- 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+ e, o9 [" f1 e0 x
标 题: 加速matlab运行的三重境界8 h! [5 W8 j' o$ B
发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)
& r$ A2 K2 a* C0 Y& H. w& i; S) U
加速matlab运行的三重境界
( U8 h0 I! j" E- `# t4 V+ J5 v# }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% R& n) C" u) F& I1 R, K2 S: h
%%%%%%%%%%%%%%%%%%%%%%%
. n6 R! n6 L9 e, M2 p; M( A一、 遵守Performance Acceleration的规则
* n) u5 k4 E# _ d. w二、 遵守三条规则
; z: E, e) K; Q) O4 N三、 绝招
2 }' Y# A& ^, ]% q- d
/ V- V% r- a5 W% B5 _" ?2 o%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
, Y+ n( v' {0 I) c%%%%%%%%%%%%%%%%%%%%%%%" D, h. \) ]; `! `% `5 v3 k1 z
一、 遵守Performance Acceleration的规则
7 D4 ^/ ] q8 W( u
$ j6 N9 ?3 X6 Z5 x- e9 ^( s关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将9 f2 k ~6 j5 h% [/ S
其规则总结如下7条:
1 e: P: d9 }. y# u1、只有使用以下数据类型,matlab才会对其加速:2 z1 ~6 ^/ ^) J. ?3 [
logical,char,int8,uint8,int16,uint16,int32,uint32,double
2 M; }! k$ ~* r( f) G而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu" s0 p* B N) z# n
re,single,
' U0 `! Z! g2 ]$ g, _8 A
3 C, i! }: t, Q( L$ I8 }function handle,java classes,user classes,int64,uint64
; R8 n$ N% W7 c0 X* B2、matlab不会对超过三维的数组进行加速。
3 D# o" F3 `- y; |2 Y+ \3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
* y7 T% E& b( Z来表示;* q i4 P0 u% H( O" _% f; ]2 l. l: Z- S
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
4 n' s; @$ s5 W据类型,只使用4 k) t$ w5 }" d; K- n
三维以下的数组;c、循环内只调用了内建函数(build-in function)。! o0 P. q1 a6 y6 U
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
7 ~# z( h3 J3 d6 B5 \! u加速运行。
: {8 D( ~+ g5 K& d6 O* h4 g$ O; B5 C5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:' m) [7 L" g$ ]! ~- C
x = a.name; for k=1:10000, sin(A(k)), end;' F& ^, ?9 C$ N$ p9 @
6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
% `9 j' M2 h+ m. b度。0 M `8 ~9 P* j
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低0 t$ _* _$ ?1 J- d8 x
运行速度。
( [( X8 p3 Y* @8 ?6 _; B9 ~* o" k1 q& ^1 m% v# [
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$ n5 V4 e: e! s
%%%%%%%%%%%%%%%%%%%%%%%" ^6 e+ D3 H; y: @6 A
二、 遵守三条规则
' O/ \1 p8 y3 d+ m1 R$ U+ u5 L0 q; A$ K/ d) V) B
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic% t4 I3 K. K" B4 i+ W) l
h means it is designed( X/ C4 K$ v! O# Q, C# [4 p
) ]% e0 e) h# p: g n
for vector and matrix operations. You can often speed up your M-file c
- q8 q0 O0 F/ Y% r6 ?) ^4 Pode by using
: W. y9 I4 w% t; J, [ pvectorizing algorithms that take advantage of this design. Vectorizati
. ] a% @/ c( } yon means converting2 G: o$ I0 o ^! E, C& v$ r
for and while loops to equivalent vector or matrix operations.”。改进8 z; m8 Y+ F) M& n% @0 b7 ]
这样的状况有两种方法:+ F, S* v, U5 o$ }7 W% C
% n, F/ r2 ]$ G1 ~a、尽量用向量化的运算来代替循环操作。如将下面的程序:, K: t+ ~ w" r6 u
/ f5 g. G" l: P4 ~) h7 d
i=0;
" w/ @- C1 R9 J* s% wfor t = 0:.01:10/ U3 o0 H' Y8 w2 `" J: d7 B
i = i+1;
% X) ]- r' F4 e( |& Uy(i) = sin(t);$ X# A! x8 c' }
end( u# o2 L, x G0 r1 k3 s; h% K/ E3 ~
替换为:7 q2 H9 y3 ?' s& S- }+ P
t = 0:.01:10;
( `" J7 g% `0 I- E: iy = sin(t);, `0 ~$ U5 S6 z- f
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i
! L5 Y& E1 r4 A3 k/ b- v9 ?& }7 upermute、permute、4 E/ ~8 Y. Y6 S$ a
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums$ k1 T9 p0 `8 l4 o0 M
um、ind2sub、
; H' D# z; u% e1 g0 R6 }+ Yndgrid、repmat、sort、sum 等。! K7 F V" j W
- t4 e8 ]& E: K: F1 {2 Y; c请注意matlan文档中还有这样一句补充:“Before taking the time to. p6 n8 ]! J1 O! D; t5 @( ]8 g) m
/ c' o1 x: b# l: l6 D+ ]vectorize your code, read the section on Performance Acceleration.2 E; X# Y, Q8 D% r: {6 ~
You may be able to
- m$ h8 a3 }# H$ J% U! N5 f, Lspeed up your program by just as much using the MATLAB JIT Accelera
% N% p# N, w$ i$ }1 w0 ]7 b: ctor instead of
1 ^' J, s2 N$ ~ C6 @! [vectorizing.”。何去何从,自己把握。! ~4 b% M% L& v% E' Q$ \ L* s ?
2 z6 i! g# E# }2 H( j" H
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
4 g% _" s) p/ j0 W9 T行循环次数少的,
( L8 C9 R7 ~& w7 A; A% |$ V内环执行循环次数多的。这样可以显著提高速度。
6 Q3 q/ M6 W+ m, h
8 R' ^. V! N* t2 ]2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on9 ^8 e- _! ]9 _; m! J5 m- w9 D
es、cell、struct、8 u. ?% i! f- D1 S& C$ H- b
repmat等。
9 ?5 w, l6 }. T. n& M0 vb、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:* _5 O: h, f, h6 n B1 y
9 c' Z$ Q% _$ \9 RA = int8(zeros(100));2 S6 \% ^# K$ ]
换成:
0 U/ Z. p, K& B) f8 A8 IA = repmat(int8(0), 100, 100);
1 }) W: v5 E. L; Y0 i# k9 jc、当需要扩充一个变量的大小、维数时使用repmat函数。: W1 |- B. i4 s1 ^' Y$ U
9 h% p! O9 e8 x% ^/ S% r, E/ @3 Q* G3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。+ a9 H, R7 y O' k! i$ b- U
b、使用Functions而不是Scripts 。
+ p# T7 O/ p, k0 n/ s
7 B, F! Z7 k6 T/ \7 j) [%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%8 g4 Q! c! d1 V, p
%%%%%%%%%%%%%%%%%%%%%%%
4 s. p8 k+ G( {5 ^) O% x- U三、 绝招
) ^- X! h% a: k5 V9 H; h$ X/ l* Z5 R2 z) _5 E' }, T. v& l' w
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。- P B- G- m# J1 \# M
1、改用更有效的算法: X8 Z, N6 q' P; A
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
2 C- b- |! v* \ T+ L7 S' Y }% B. S+ i
关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
* }6 V/ R6 ?* v% p- M& } K语言文件,VC编译 |
zan
|