发信人: fork (撒哈拉沙漠的沙), 信区: Matlab+ U s4 I% L: m2 u4 ^ 标 题: 加速matlab运行的三重境界 发信站: BBS 哈工大紫丁香站 (Thu Jul 1 14:27:30 2004)5 Z( s5 ~1 ?2 c2 ^0 P; Y) s 加速matlab运行的三重境界
1 s4 U, L; }% I9 B% s一、 遵守Performance Acceleration的规则 关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将6 ]1 d& e; N: j, ` 其规则总结如下7条:* n& H# o4 Q' e' I 1、只有使用以下数据类型,matlab才会对其加速:$ ^/ A$ O' v5 d2 O' |0 V' S) r$ c logical,char,int8,uint8,int16,uint16,int32,uint32,double& z/ W" x; g; Z+ f5 v 而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu8 q9 b- y% g$ b& z re,single, 0 \4 M) s$ d9 }8 ~% |# { function handle,java classes,user classes,int64,uint641 a! P8 n6 Q; a6 L 2、matlab不会对超过三维的数组进行加速。' d: m' W: g! `& z, r6 e 3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 来表示; b、for循环内部的每一条语句都要满足上面的两条规则,即只使用支持加速的数 据类型,只使用* R* C# x1 M M4 Z0 x& T 三维以下的数组;c、循环内只调用了内建函数(build-in function)。+ E" g' B+ n; W 4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将 加速运行。 5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句: l3 V6 i q1 I$ M x = a.name; for k=1:10000, sin(A(k)), end;; |' A6 O+ H2 |+ e* c 6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速6 {6 ~/ ?. r, }' k% Z 度。4 i/ T* \ `2 }' h- Y 7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低# }# Y1 Y4 a3 @. i! m! R 运行速度。
4 z! }. Z" L6 W& V二、 遵守三条规则 1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic& O+ ]7 m" }" T$ ?* I h means it is designed 5 Q5 ~" e: T5 t5 }) k1 ?: B7 X. u+ y# ?- } for vector and matrix operations. You can often speed up your M-file c. F, [9 e. D# N) j4 k3 _: }4 l ode by using7 g. s; `7 X4 j8 ?6 K( B- L vectorizing algorithms that take advantage of this design. Vectorizati on means converting2 v' E. r S, Y5 f for and while loops to equivalent vector or matrix operations.”。改进 这样的状况有两种方法: " u+ F4 r% t# B0 k7 W/ I a、尽量用向量化的运算来代替循环操作。如将下面的程序: , L$ q4 S) D) ?& v5 V) s( n i=0;6 @' N" M3 x1 L9 _ |. Z for t = 0:.01:10 i = i+1; y(i) = sin(t);: T: n- e3 [: C9 V4 i end 替换为: t = 0:.01:10;+ L6 }: c2 A1 i/ U W5 e9 k y = sin(t); 速度将会大大加快。最常用的使用vectorizing技术的函数有:All、diff、i permute、permute、; [/ Y6 g5 g& ]" V reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cums um、ind2sub、, F2 x8 j( [1 e! @ ndgrid、repmat、sort、sum 等。 " E, u& j( |& X. p5 @) u 请注意matlan文档中还有这样一句补充:“Before taking the time to vectorize your code, read the section on Performance Acceleration.5 ]; c. X) L2 x# t4 v9 N8 N You may be able to9 ]6 ^! M2 y; w; _$ {: H4 \( y- u speed up your program by just as much using the MATLAB JIT Accelera tor instead of; n2 a$ {( Z! O vectorizing.”。何去何从,自己把握。 b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执 行循环次数少的,( V" e2 d2 y4 Q6 ~7 y0 e2 J1 N; ` 内环执行循环次数多的。这样可以显著提高速度。 2、a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on es、cell、struct、 repmat等。+ w1 m \- @0 Z b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码:4 ]" Z7 @5 Q! q6 l( v7 D# t 0 x: y$ M9 I% e8 ?8 S, C A = int8(zeros(100));5 S2 d4 A8 {# s2 x2 Z 换成: A = repmat(int8(0), 100, 100); c、当需要扩充一个变量的大小、维数时使用repmat函数。& t1 N1 d) ~( |( H1 x2 ` 0 m" C& k& j; c, d5 O3 }) |, t3 S$ s 3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获得加速。 b、使用Functions而不是Scripts 。7 @, _0 h# J! }3 s
7 Y- C4 R }$ p, W) N三、 绝招4 L! o4 H3 O) ? 你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。 1、改用更有效的算法 2、采用Mex技术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。 * s) ]3 J: o/ n. N5 J! j 关于如何将M文件转化为C语言程序运行,可以参阅本版帖子:“总结:m文件转化为c/c++6 M8 f9 A/ ~: e3 ?6 H1 M 语言文件,VC编译”。
注意
加速之前应该先测试9 G, y8 U9 Z1 o! x/ } 使用profiler可以获得程序各个部分的耗时 如此就能高效的加速
# W7 y6 \0 _6 j7 F/ {6 K) F因为有的时候导致速度变慢的原因是逻辑结构不合理,* V1 [& N! n5 n$ R4 X, e) u! p7 ` 而不涉及程序技术
# l9 @4 u( H& l, R* j
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |