|
非常实用的Matlab编程技巧。可以试一试。
; A8 |9 Y' s4 C; g0 \* l! dCTerm下载文章: 紫丁香★+ `! A' w1 N% G% k# L3 @
9 a7 K q' j2 k
发信人: fork (撒哈拉沙漠的沙), 信区: Matlab
8 M+ `1 L, X) Q标 题: 加速matlab运行的三重境界
6 ?7 ?. C: ?6 z S; r0 ?1 B$ C发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)& @1 y# V. `; ^' p' l/ W( k: U
# r- [: F4 Q0 ^9 O, \( ?& T9 S
加速matlab运行的三重境界
- U6 _ F. @, s, B3 E! q9 z( u t一、 遵守Performance Acceleration的规则
* I: `" c6 `0 e/ e7 O7 x: |0 N! }6 i二、 遵守三条规则
7 A0 a& z7 V+ B5 f0 ^三、 绝招
3 c4 Z B/ _: i/ {% s7 v6 D
一、 遵守Performance Acceleration的规则
8 [0 l( {- w; M$ g* d4 T; f
* t/ g$ [: z0 |2 B! W$ P8 W! {& v关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将8 J" X3 X, z7 d8 {2 O+ {
其规则总结如下7条:; K1 P; n9 n, |1 n1 `
1、只有使用以下数据类型,matlab才会对其加速:) {* |) r2 j* x, o% g4 e/ ]
logical,char,int8,uint8,int16,uint16,int32,uint32,double8 Q! R- A0 X( ]( t- _/ |
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu# M- E. P4 c1 Y2 S- C
re,single,
: {, \' Y: T' I1 [
% S9 I k& @* O! q( t1 ofunction handle,java classes,user classes,int64,uint643 M( [2 p5 [% J* q3 k" _' J; N
2、matlab不会对超过三维的数组进行加速。
) C6 i7 m% m* a+ e% O3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值
! K) X( p# l* C; P/ I! n7 _来表示;
, X4 Z2 Y# r6 \; rb、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数
3 u2 B* I: J$ x" [! k( }据类型,只使用! F6 ~# N4 G- H- A& [2 E
三维以下的数组;c、循环内只调用了内建函数(build-in function)。* u4 D: v6 ?. b* D! F0 o
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将
- q/ _4 K: T+ |加速运行。( u* r; ]' }) n3 d( o7 r; M
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:7 N2 L8 c+ m) }& D) m+ m ^
x = a.name; for k=1:10000, sin(A(k)), end;
7 P2 t. b2 B. T, f* [$ h6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速+ [7 T! h3 H4 F
度。
Y6 c6 }7 [6 v" P7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低
3 a8 j/ b3 u6 O1 L5 r# R运行速度。' A" [3 H7 j: _% u) X, u# z. b3 z
6 E* _+ n0 v7 [$ K. w+ {
+ c! v1 }( X" h2 n9 H2 d$ ^
二、 遵守三条规则
l3 U/ i( U: h
; o! d a: w+ j5 A/ G m1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic
F! R# W0 I( o5 Ph means it is designed+ o3 Z6 y) C3 R2 U
! y8 U( G: x/ ?3 G: a, C" ]
for vector and matrix operations. You can often speed up your M-file c! i) j3 o& B/ }4 M9 d: W" r! g' V- p. ~
ode by using8 |7 Z. w, C" o4 V2 u, c4 j
vectorizing algorithms that take advantage of this design. Vectorizati' Z9 v8 i7 `) S% ?; c I1 T
on means converting
; h5 p" V, v4 P5 Cfor and while loops to equivalent vector or matrix operations.”。改进! F9 G4 [5 G" ~
这样的状况有两种方法:
& f& _' @9 n! G! t0 e) Q8 a8 l: }6 u- J
a、尽量用向量化的运算来代替循环操作。如将下面的程序: r+ B; i3 M4 c" C u. O
R! ?0 |3 F" ni=0;
/ s7 F+ s; Y# ?6 [# l8 vfor t = 0:.01:101 V( m+ Z, I4 r* A. R
i = i+1;
7 N$ X9 L3 D' u8 f cy(i) = sin(t);
+ N& W' E" |5 @" O3 c) N9 [end
* ^7 D% ^( `# w7 `6 h+ S替换为:1 M L, J/ v3 Z; G. B) L, b; L+ X
t = 0:.01:10;& ?( y! c! Y# }) ^8 A' _4 }& a
y = sin(t);4 `; x: ?- c) m [) h- f
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i# Z% W" M8 Y, H# G7 v
permute、permute、
" K8 R5 ]4 ~1 Z' K" ereshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums$ G: |* }* h! m+ `# n
um、ind2sub、% _+ `/ C! N2 x
ndgrid、repmat、sort、sum 等。0 V6 d: V# G. c. @: z
- \' K, R, F8 \, y4 W% c$ |请注意matlan文档中还有这样一句补充:“Before taking the time to
. M- T. F" ^1 X& X: X% Z
: t9 W# [& ?; N+ U& z# y# [vectorize your code, read the section on Performance Acceleration.
& Z, s* u' N5 H' h- ^You may be able to
: h# A* p' q* F, O3 ]# d) @1 Zspeed up your program by just as much using the MATLAB JIT Accelera: c( b$ i/ r. d
tor instead of8 t0 p6 _+ v0 E/ r! @
vectorizing.”。何去何从,自己把握。
/ W+ Y7 S; q: a9 I- Q" Y+ Y" g9 T+ |3 N, O% c8 c
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执1 i# l& T q( ]7 C" o3 r
行循环次数少的,& q, k9 K. D% O% Y; d
内环执行循环次数多的。这样可以显著提高速度。$ {1 |! P- F( r V3 C6 L: w
6 X0 n$ M; p: z6 P2 T! h+ R2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on# D P; O+ D6 s- \
es、cell、struct、
. l8 K3 D# c; V% h: c Mrepmat等。6 X3 `; q. ]5 w( E) V$ n
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:
8 p0 D1 r6 c5 |* n+ W( ?" L1 m* J2 V4 e
A = int8(zeros(100));1 e; Z2 a& y3 O9 k. y
换成:
& {. ~4 B2 H0 fA = repmat(int8(0), 100, 100);; T1 R6 }( f( }* {5 G/ Z6 n0 F; E
c、当需要扩充一个变量的大小、维数时使用repmat函数。
3 w, o# n! O9 p) M# L1 ]; I0 T
) p# a; R( d c3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。
; I k: o; O" J5 ]b、使用Functions而不是Scripts 。
* k1 K1 T; c8 X* B2 x" K" c
6 s+ ^. n$ Y1 {: E4 a- b I6 \' A2 M) T7 p
三、 绝招1 |& d T, w2 q, L# @
* N% U) p/ E( a! s
你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。
( a" ~- D3 }2 `8 {6 D1、改用更有效的算法
. x% c' b8 k _! f1 o& I% D2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。. F5 y8 A& o* M
' }9 n( X4 f4 \9 _5 G$ S+ B, Q
关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++/ [+ x9 Z8 w" }0 f* [
语言文件,VC编译”。
" n# ?; A! ?. D" K% x3 u |