数学建模社区-数学中国

标题: [转帖]加速matlab运行的三重境界 [打印本页]

作者: god    时间: 2005-1-20 10:27
标题: [转帖]加速matlab运行的三重境界
信人: fork (撒哈拉沙漠的沙), 信区: Matlab6 \. y, J/ Q8 l# u
标 题: 加速matlab运行的三重境界  N( l: F$ I! U# A5 e+ B: x
发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)& E( ]  T6 G) k$ Y

& [2 J5 h, ?- _* T$ \' ]# y加速matlab运行的三重境界
7 Q4 K$ g1 u) K" i
; w  }) ?# [6 c1 f, K' g%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%3 V* I" S- q, P8 D3 o
%%%%%%%%%%%%%%%%%%%%%%%
; }% V, o5 Z5 L  Q1 u- N! O- y/ w一、 遵守Performance Acceleration的规则, a) r2 N; ]) W. A8 I
二、 遵守三条规则
7 c" u, k4 ~4 [! s5 z! }5 N三、 绝招
# o3 b' c1 m6 U$ _8 |  j* ~2 ]# L- `$ }4 z
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%3 W( C* [) U4 b
%%%%%%%%%%%%%%%%%%%%%%%
& N* l5 c+ v) ]" g; j一、 遵守Performance Acceleration的规则: ~! y& o; n, ]+ z4 J) |2 w

& U4 x7 N$ l7 K- q; @关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
  \6 m  q) P3 ?1 s& J其规则总结如下7条:6 t1 j/ ^  f- W, S
1、只有使用以下数据类型,matlab才会对其加速:
( C( Z$ _' y- Xlogical,char,int8,uint8,int16,uint16,int32,uint32,double
: I- F8 Y' f* r- K4 ~而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu. P1 Y7 a5 y" o1 i
re,single,
) p( x. o& n8 ?4 }( B4 p; a, A
. Q0 E8 N  ]) P2 P$ z. Pfunction handle,java classes,user classes,int64,uint647 g& i( P/ |( C# J6 n5 L1 t1 g
2、matlab不会对超过三维的数组进行加速。& M. {6 P5 Y5 ?0 n
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
4 `5 f/ h! M' S# i( a9 G来表示;! Y; U) J2 m  ?0 y+ Z! d4 M) ]8 a
b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数  M" A; O/ F/ \3 V5 F
据类型,只使用9 V  d+ C( A  w; j! J6 R/ p  P
三维以下的数组;c、循环内只调用了内建函数(build-in function)。
7 I, h( I) d$ n' r4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将7 L3 k/ T6 M2 u1 F! @
加速运行。
. y9 x5 [5 h2 c' B4 v5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
6 y' R3 n  t" b+ lx = a.name; for k=1:10000, sin(A(k)), end;7 u  y) F+ m$ u3 ^! p, x
6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速4 ]$ S" M- s' m( j
度。- H" \7 |! E9 ^% X, |& W" {
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
* B  Y# g; b: _% ?3 @运行速度。6 ?7 g4 P0 R. j; `. a( [  j/ m

; T7 c! d  N) f6 A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
, ?% B" O! y8 |6 E& V) N1 N%%%%%%%%%%%%%%%%%%%%%%%$ M  q% t) m% @- g$ _
二、 遵守三条规则+ p  P3 p  V6 _

& U+ T, W: j$ C7 |& {. g. |1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic
" t8 x4 L& W* a" [3 {0 Ph means it is designed
# {7 ~% w; i/ W1 d  |5 C* p& L
5 Q8 c. t& X+ e# ]for vector and matrix operations. You can often speed up your M-file c
# J) C$ ^( S* N# ~6 Node by using( @  A4 x+ C0 `: \
vectorizing algorithms that take advantage of this design. Vectorizati+ |& N' G6 c0 p: P
on means converting
$ r8 ~: O( {/ O- ~. z' Q8 W9 R; _for and while loops to equivalent vector or matrix operations.”。改进) ^- t! D. B; h3 K, {
这样的状况有两种方法:
( A5 g9 @: Z! d$ j$ B6 J0 V6 O. {9 b0 b( n
a、尽量用向量化的运算来代替循环操作。如将下面的程序:3 {1 t0 @9 Y4 |
4 p2 q* v) W, q. |
i=0;
7 [- K) m9 ]* d) K$ [2 ofor t = 0:.01:10
' B8 f# _1 w: M5 Y3 B) W" j- S8 l& Yi = i+1;
" W% P1 h3 L1 M+ sy(i) = sin(t);
: d: n0 H# `  F6 {# ~end
( m- `0 J$ W: ?6 e替换为:# A6 G8 X' c" a. N
t = 0:.01:10;
+ u* ]) }) q* l2 n- \y = sin(t);, B) C1 x, b! b0 l9 U8 S
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i) a  w0 L/ y6 l$ _- c; T. B
permute、permute、4 B/ z1 {$ P1 k
reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums5 j3 T! M( G1 Q. F
um、ind2sub、
' P( x; _; E6 {4 jndgrid、repmat、sort、sum 等。
; f8 T/ d1 Y- W5 [! U! v  M! L" u0 T9 {& ]
请注意matlan文档中还有这样一句补充:“Before taking the time to
6 h& A. x: a: ~1 Y% w; i; W. W5 M1 C9 N  c( m
vectorize your code, read the section on Performance Acceleration.7 E4 v: [9 m# N& E3 f, G
You may be able to! i, U! k8 c" p; ~5 _
speed up your program by just as much using the MATLAB JIT Accelera0 Q' R- F- Q3 Y8 S9 L+ L. v: e6 G
tor instead of& h# |$ u; _) x6 v  {+ c
vectorizing.”。何去何从,自己把握。
$ L" L3 P( n  I7 o) Z5 C4 G5 e! f5 E8 f
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
$ }* K, o1 n: w0 @行循环次数少的,
7 N/ `6 H, i% Z% Q! v8 r$ f内环执行循环次数多的。这样可以显著提高速度。
9 O) A$ B: a: l# U1 j& ^) O- _. b
2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on
, s' q& {/ l6 [* {9 |es、cell、struct、' e0 s$ g& T* m# `
repmat等。! \* b7 E  y; v4 R7 L* \! \* @
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:7 f' K# E/ s( e8 g, {/ S1 z
6 D5 ~: v# f  i6 V
A = int8(zeros(100));
, |! P( }3 H4 |: }换成:
: `" E1 @) [0 G3 q: Q7 e' Y8 c/ pA = repmat(int8(0), 100, 100);+ i1 ]& R3 k7 T8 I  R, R* o  P
c、当需要扩充一个变量的大小、维数时使用repmat函数。+ `/ F" T' B# N( @
. c$ Q; G. X& k0 H' M1 s
3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
, ~) S% n; t" |: Q1 ^8 c! ]- Jb、使用Functions而不是Scripts 。
' B3 b% n# h. |3 f! L% ]$ M
1 V% A4 A# ]& Y& N+ j; }& y%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# t1 b! q8 G0 W6 Y8 t" K%%%%%%%%%%%%%%%%%%%%%%%5 j# n, h2 u0 V) S8 G: s
三、 绝招
/ w( I" q2 T6 w9 l! o: G- o" ]- U- T" X! N4 R) K" ^
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
" V' u1 {$ T1 T: c% O0 Z- }; i, M1、改用更有效的算法2 I0 m- y& ^$ m. t& k  i
2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。
5 `2 \! K' W/ b# B0 ^
4 J- G6 S5 _& M' ?, z" }关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++; [( O8 }( c, Z% R  d  R
语言文件,VC编译




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5