数学建模社区-数学中国

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

作者: zzwszj    时间: 2004-12-21 11:00
标题: 加速matlab运行的三重境界

发信人: fork (撒哈拉沙漠的沙), 信区: Matlab ! P5 e9 v5 c6 b2 c标 题: 加速matlab运行的三重境界 # _9 e [* [+ o. V* Z0 f0 t发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004). D5 j4 F7 {" R3 e4 V" t) X, z / T+ @! A" c! f加速matlab运行的三重境界

% ~ V& q! g% D! p% ^# z9 x) r, O h: J, _$ T6 E% ^, X

一、 遵守Performance Acceleration的规则# `, X7 p2 x9 x8 |/ q: M7 k ' d8 o5 i! ]; ^. I: ~$ k* O9 H4 R5 R关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将7 a( [+ [, z( s: v/ p0 @- _ Y 其规则总结如下7条: - Y8 \ q4 z8 p1、只有使用以下数据类型,matlab才会对其加速:5 U% i# N6 ?! T4 H8 }; s logical,char,int8,uint8,int16,uint16,int32,uint32,double * y% Y$ r1 |" C& _+ \% N& r而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu" l; y/ i( ~/ w* S7 D+ Q re,single, $ K! u* p8 @8 l# k, d f8 {& M4 k5 h% t, g function handle,java classes,user classes,int64,uint64 4 ?' p, B/ s( B: u2、matlab不会对超过三维的数组进行加速。# P+ {- D- L5 M! m$ @2 t, ]7 B. M 3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 ( n9 L3 U+ K# b9 m) _; ?来表示;4 S+ t J& B. a0 v8 X b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数/ t7 h0 U+ {) Z1 M8 U" r- u) y 据类型,只使用; J' |' r0 q0 z5 s+ K0 ]$ w" r; a 三维以下的数组;c、循环内只调用了内建函数(build-in function)。 / W7 g" R& U# s. X! C4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将8 ~) a- C) q% l: K- |3 a9 x 加速运行。 5 A: F6 Q0 ~5 V# |! h5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句:$ m1 @5 n& _& c) h* K; l( L) g x = a.name; for k=1:10000, sin(A(k)), end;8 D* H! ?( F! }" P$ M! G 6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速4 U5 h2 S D8 w1 W0 E# l 度。; f/ i6 Q- O- j" _" k/ i3 ^! c, m 7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低6 q& b2 m( s1 `! U7 r 运行速度。2 V2 N2 r$ D: e, E7 V1 z0 I

: A2 t" X+ }* q8 d+ W" H

二、 遵守三条规则* X: z( t$ i6 ?( L d 7 R, m3 E$ U% b4 L( Z1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic + `) w+ U2 o/ Z% [5 Xh means it is designed + X) ^: E/ |" A& `; R ( `1 E. P+ U( Y) f' N( G, Vfor vector and matrix operations. You can often speed up your M-file c& M0 d8 ?4 z5 V; |7 E% m, f$ V B1 b ode by using $ u+ ~. ?& C+ `3 Svectorizing algorithms that take advantage of this design. Vectorizati 2 h, T0 T/ G+ Yon means converting3 I* X' ~3 G" p6 F9 e$ B* m for and while loops to equivalent vector or matrix operations.”。改进 + q5 ?/ w" V0 ]8 M4 o0 s8 T' F这样的状况有两种方法:1 j- [7 ~* E% i" t, E9 Q( M( m & C( x6 P9 e5 Qa、尽量用向量化的运算来代替循环操作。如将下面的程序:0 ~! y5 F/ I" h' p' ^) n* v$ C : m- E3 M# k) o. e q: N' X i=0; . p# G* O8 C% i0 h: ?for t = 0:.01:10 4 c1 E# _/ ~. b7 E$ J/ y) q" Q$ }i = i+1;" p5 [. [# [: ^ _5 q y(i) = sin(t);, L7 s L) f3 c3 G end + X2 n d8 |6 Z替换为: 4 F7 e, C6 n; u# v' G4 }t = 0:.01:10;% l% t0 | S/ i; v6 g9 | y = sin(t);! }" C. \+ e+ l# M/ y( l 速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i - Y/ i1 V1 P) y7 C1 \permute、permute、 5 U r, O% x% j: ]reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums8 b5 _: H Z8 V) w# {' q! P um、ind2sub、 ! m3 k% f( w/ t2 F, rndgrid、repmat、sort、sum 等。 5 E$ f: h' a# i1 a2 C3 V9 ?/ \1 k ' G- x9 A' L1 G4 g0 Q$ b7 s请注意matlan文档中还有这样一句补充:“Before taking the time to # n0 \5 U9 k" G% C+ A; I4 P" k / L1 c+ g1 ~+ f1 h6 Evectorize your code, read the section on Performance Acceleration. - L2 F( m9 t; y' e: |You may be able to7 S/ H- x: G Q0 i speed up your program by just as much using the MATLAB JIT Accelera4 E$ n) Q- N* F$ r/ f! J tor instead of ' F3 D/ E- A0 V+ f0 A8 rvectorizing.”。何去何从,自己把握。/ \; b/ Y' ~# h- \+ G : j3 M# j/ k g; H# ~4 H" b b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执 8 G% ^1 S# ] f, j行循环次数少的, # b7 ~1 O8 P" W& C" } A+ [# Y内环执行循环次数多的。这样可以显著提高速度。4 _: l, g- j% V& d' ` : ]9 m9 u0 U! j 2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on& v3 |; D% l. q5 F+ L' }4 _" ^& f6 x es、cell、struct、1 H( c/ E1 f( }" ~) j* Y m repmat等。. ]4 E" Q1 B& H7 X b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:9 h( b$ [5 R) W6 | / b5 k r, H1 V( C+ y5 {$ bA = int8(zeros(100));$ K9 _4 Q. r+ t! F* `! s 换成:: }6 t4 Q; G& s- [! b$ W A = repmat(int8(0), 100, 100);. M8 g1 p1 Q3 f( N8 M c、当需要扩充一个变量的大小、维数时使用repmat函数。" w( ]' i j) h. p H% s ) j, q/ \% b5 B+ v/ R9 T 3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。 2 o8 o3 V2 O0 `; z2 o$ yb、使用Functions而不是Scripts 。 ) ^/ s3 O- p$ E' r- b

7 ^' I, V& @; H. E

三、 绝招 L) _' f. f6 O: P# R$ [& C5 [8 P L 你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。$ o; G: l: ^3 l8 r- Q( } 1、改用更有效的算法 3 x7 \8 j# B1 O4 @5 ]$ g: c* T2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。) m& v; |9 B1 b W" X6 v/ Z 6 G# z8 G/ V/ B7 @ 关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++ # Z$ W6 v( ]7 `. f语言文件,VC编译”。


作者: fup    时间: 2004-12-21 16:00
Great.
作者: ornewuser    时间: 2004-12-22 11:47
好文章
作者: zzwszj    时间: 2004-12-22 13:01

注意

$ x; c. z2 k' f& p/ ~! P6 F

加速之前应该先测试/ q! ]2 \, L) ~ 使用profiler可以获得程序各个部分的耗时# Z/ T1 p) g' z5 _ 如此就能高效的加速. U* R* @" H% G1 d' ~

7 E) b# y- |* X5 I' K ]+ |- }# M' S

因为有的时候导致速度变慢的原因是逻辑结构不合理,: `4 w0 {: ^8 {/ P' Z! ] 而不涉及程序技术

0 r& b3 Q7 [* w8 r7 K2 k* N* d, B


作者: hamburger_2004    时间: 2004-12-22 21:10
收到![em02]
作者: hamburger_2004    时间: 2004-12-22 21:12
多谢掌门人,对俺的帮助太大了。
作者: 布赖    时间: 2005-1-4 18:13
有没有经过考验的????????




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