数学建模社区-数学中国
标题:
[转帖]加速matlab运行的三重境界
[打印本页]
作者:
god
时间:
2005-1-20 10:27
标题:
[转帖]加速matlab运行的三重境界
信人: fork (撒哈拉沙漠的沙), 信区: Matlab
6 \. 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- X
logical,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. P
function handle,java classes,user classes,int64,uint64
7 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' r
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
7 L3 k/ T6 M2 u1 F! @
加速运行。
. y9 x5 [5 h2 c' B4 v
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:
6 y' R3 n t" b+ l
x = 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 P
h 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 N
ode 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 o
for t = 0:.01:10
' B8 f# _1 w: M5 Y3 B) W" j- S8 l& Y
i = i+1;
" W% P1 h3 L1 M+ s
y(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、cums
5 j3 T! M( G1 Q. F
um、ind2sub、
' P( x; _; E6 {4 j
ndgrid、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 Accelera
0 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# U
1 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/ p
A = 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! ]- J
b、使用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, M
1、改用更有效的算法
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