数学建模社区-数学中国
标题:
[转帖]加速matlab运行的三重境界
[打印本页]
作者:
god
时间:
2005-1-20 10:27
标题:
[转帖]加速matlab运行的三重境界
信人: fork (撒哈拉沙漠的沙), 信区: Matlab
& H0 S2 a1 X) T% q& t3 u" U
标 题: 加速matlab运行的三重境界
+ r: E8 A. J4 P! t
发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)
& _2 ?2 {, [3 `& h3 a
# v$ E% _; N0 F( H( H, P0 m
加速matlab运行的三重境界
6 u0 \( M3 v9 }! V% a
0 e' g5 t% _; u, K
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 H! e) i: C6 F* z, J3 E
%%%%%%%%%%%%%%%%%%%%%%%
- F3 c+ C' m+ x; b
一、 遵守Performance Acceleration的规则
, S2 B" w, V+ o' M& m3 g6 r' `! U
二、 遵守三条规则
* ]% g3 e, n/ \+ E7 Z0 \
三、 绝招
% \2 a7 o% b8 U( x
0 a. k. y- y0 X8 y! k
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- v2 W3 V( U- [9 N
%%%%%%%%%%%%%%%%%%%%%%%
! c: ~- Z* B' w6 d( r; i' @/ {2 |
一、 遵守Performance Acceleration的规则
! w5 a4 W: r; a7 Q! s+ L0 C% v8 k9 u
- Q4 q3 X }) d1 i8 J0 ~
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
& t3 [5 j* z. v& d' \7 j
其规则总结如下7条:
" F& Q" Q4 w* p
1、只有使用以下数据类型,matlab才会对其加速:
; ?: Y) ~/ t" N6 o! m
logical,char,int8,uint8,int16,uint16,int32,uint32,double
: U0 q! q$ ~: \8 S# H
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu
' ~1 ~. A& U4 t* Y5 B& q
re,single,
3 J; u( ^1 G7 V1 ]/ ?/ G
/ V7 d! b0 A- P
function handle,java classes,user classes,int64,uint64
! A" ~5 z% ~% c B1 Y1 M
2、matlab不会对超过三维的数组进行加速。
8 h' j; l" u' a* M9 \% f
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
4 ~, q2 N9 r2 E6 M% f [, E' C5 z
来表示;
! }8 d8 }; H$ R6 R- s( n* ?! A2 a
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
% T2 G, H, J6 a" r( M* q8 y
据类型,只使用
4 o) o2 G( L& u. i" M# ?6 ?
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
0 s( w- g) U }/ s4 c5 o, i
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
2 M( ^+ Q! S/ s/ ^, C; Q
加速运行。
9 V( O2 y. s7 r) K+ \6 P
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
1 g1 U: Q3 \' R1 j8 m' g$ S: E
x = a.name; for k=1:10000, sin(A(k)), end;
4 ^. J# `0 M' P& n) u* q! P7 g
6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速
7 ~- t3 o( H8 D, K4 |3 e" }
度。
! l, p2 M$ h0 j3 I' N# `
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
' z% [/ ^& m$ \* o( Z5 e8 o( t
运行速度。
) _' h$ J" r# N
) [) J3 u* W9 u2 G) u
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
) f- i$ B; ?; j
%%%%%%%%%%%%%%%%%%%%%%%
! ]5 `- f6 s) N3 G* `+ D/ r$ W2 H
二、 遵守三条规则
, M3 }8 r0 l5 N1 n
8 r- T- k& o! M1 D
1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic
" b3 m v9 I7 |- Y! z5 m& _
h means it is designed
5 f L1 s, q/ J g# t* G9 G* O, j
; Q# S0 ~0 W4 E4 ~' ]
for vector and matrix operations. You can often speed up your M-file c
; b9 x/ @3 A( R1 ~1 N
ode by using
7 h1 C8 d( g) ^: Q# ]( O) H+ u
vectorizing algorithms that take advantage of this design. Vectorizati
3 R& }* x( f; W( I" C+ h: C
on means converting
4 f0 B* a$ f& i3 W( k- a
for and while loops to equivalent vector or matrix operations.”。改进
+ o, n4 s+ _4 [8 Q
这样的状况有两种方法:
- W4 Z# M/ [; B
% L8 q& A7 D! p; P9 R, V5 G8 z: I
a、尽量用向量化的运算来代替循环操作。如将下面的程序:
4 I6 s ^& j+ R( A: B) g& V
. d8 V" k: `2 v8 Q
i=0;
6 u4 ]' ?/ q/ K2 Z7 h
for t = 0:.01:10
7 S2 }8 j- ~4 R6 X
i = i+1;
! K, v" Z% V+ I. Y
y(i) = sin(t);
0 _" J- p* V$ U1 A7 ]
end
. B$ j) F4 Q) N' M2 v, @) p# b
替换为:
; {8 a2 k+ R& Q y3 j
t = 0:.01:10;
: J7 |8 a: R* a6 G2 M
y = sin(t);
9 x! C7 V+ s0 V' f4 g2 B7 b
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i
! G, H* I4 [7 L4 N
permute、permute、
$ @7 x" ~8 c }; E4 y8 N
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums
! J4 j) | V" s
um、ind2sub、
; P* H& U/ Q5 r1 c
ndgrid、repmat、sort、sum 等。
) G+ ^7 D% S6 p9 j9 C: `
2 c+ h) ^" c5 x* T' d
请注意matlan文档中还有这样一句补充:“Before taking the time to
9 D7 k. l) f' O; I; C5 o/ Q
' t5 k9 _, S! b- v
vectorize your code, read the section on Performance Acceleration.
4 |# ]6 D0 T. d
You may be able to
! G/ P! r/ Z4 g0 l" N$ z3 n- k" T
speed up your program by just as much using the MATLAB JIT Accelera
& D# b6 F3 G5 F6 t# F- j
tor instead of
6 l" P9 ~6 S8 m) T" S1 i2 G
vectorizing.”。何去何从,自己把握。
* B. O# s1 x# f' W6 ^1 X/ B
: v! C4 V% d5 k# H+ j( r& @
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
N% H/ F6 [ m2 Z! `. c1 g
行循环次数少的,
_/ d7 E9 A% a, G6 k9 D- r
内环执行循环次数多的。这样可以显著提高速度。
h1 m9 C" d M/ \7 C5 c) p
: e& Z( m0 O' s2 z( |/ t$ z2 C6 `
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
! B+ e; ]% h8 p& R/ r
es、cell、struct、
) H, |' h3 f' y$ M/ V/ _' Y
repmat等。
! ? x/ [$ W/ y. g2 F8 @& @
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
: z4 |( k0 D1 t+ i
& m( q2 l- ^9 d# I/ A
A = int8(zeros(100));
) s/ Z* R5 q( V( N: A* R$ l/ M
换成:
/ R$ G% T6 ^: F7 {6 R5 g1 ?
A = repmat(int8(0), 100, 100);
" [! _; R0 i2 z" X# W
c、当需要扩充一个变量的大小、维数时使用repmat函数。
6 x# u0 [' ]+ j* ?
5 Q z+ o, f/ o% b
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
e6 o" I. P0 k8 m) w5 K
b、使用Functions而不是Scripts 。
* i. Z, D* p5 \( K$ j% Z3 E( ]
4 n, |' w- D7 T# f( [! F" F3 P. G! V
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
" ]; U, B+ o. t- r* D; c5 r% b: v3 g
%%%%%%%%%%%%%%%%%%%%%%%
* ^; l% t1 N$ k9 Z5 a
三、 绝招
) e* J6 X& |( r8 X2 _. z' Z
. `. y/ z0 j9 u2 F9 S/ u
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
: J) O2 P/ P w7 f$ j# V" e. d
1、改用更有效的算法
" P+ w% w$ ]2 D- V6 P
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
; \' ^, M& T! N0 t- Y
0 j( W: n4 ~" a7 Z. {
关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++
( f4 q/ i& Y1 `" H
语言文件,VC编译
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5