加速matlab运行的三重境界

来源:互联网 发布:mac baren烟丝购买 编辑:程序博客网 时间:2024/06/05 10:57


一、 遵守Performance Acceleration的规则 
二、 遵守三条规则 
三、 绝招 

%%%%%%%%%%%%%%%%% 
一、 遵守Performance Acceleration的规则 

关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将 
其规则总结如下7条: 
1、只有使用以下数据类 型,matlab才会对其加速: 
logical,char,int8,uint8,int16,uint16,int32,uint32,double 
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structu 
re,single, 

function handle,java classes,user classes,int64,uint64 
2、matlab不会对超过三维的数组进行加 速。 
3、当使用for循环时,只有遵守以下规则才会被加速:a、for循环的范围只用标量值 
来表示; 
b、for循环内部的 每一条语句都要满足上面的两条规则,即只使用支持加速的数 
据类型,只使用 
三维以下的数组;c、循环内只调用了内建函数(build- in function)。 
4、当使用if、elseif、while和switch时,其条件测试语句中只使用了标量值时,将 
加 速运行。 
5、不要在一行中写入多条操作,这样会减慢运行速度。即不要有这样的语句: 
x = a.name; for k=1:10000, sin(A(k)), end; 
6、当某条操作改变了原来变量的数据类型或形状(大小,维数)时将会减慢运行速 
度。 
7、应该这样使用复常量x = 7 + 2i,而不应该这样使用:x = 7 + 2*i,后者会降低 
运行速度。 

%%%%%%%%%%%%%%%%%%%%%% 
二、 遵守三条规则 

1、尽量避免使用循环,MATLAB的文档中写到“MATLAB is a matrix language, whic 
h means it is designed 

for vector and matrix operations. You can often speed up your M-file c 
ode by using 
vectorizing algorithms that take advantage of this design. Vectorizati 
on means converting 
for and while loops to equivalent vector or matrix operations.”。改进 
这样的状况有两种方法: 

a、尽量用向量化的运算来代替循环操作。如将下面的程序: 

i=0; 
for t = 0:.01:10 
i = i+1; 
y(i) = sin(t); 
end 
替换为: 
t = 0:.01:10; 
y = sin(t); 
速度将会大大加快。最常用的使用vectorizing技术的函数有:All、 diff、i 
permute、permute、 
reshape、squeeze、any、find、logical、prod、 shiftdim、sub2ind、cums 
um、ind2sub、 
ndgrid、repmat、sort、sum 等。 

请 注意matlan文档中还有这样一句补充:“Before taking the time to 

vectorize your code, read the section on Performance Acceleration. 
You may be able to 
speed up your program by just as much using the MATLAB JIT Accelera 
tor instead of 
vectorizing.”。何去何从,自己把握。 

b、在必须使用 多重循环时下,如果两个循环执行的次数不同,则在循环的外环执 
行循环次数少的, 
内环执行循环次数多的。这样可以显著提高速度。 

2、 a、预分配矩阵空间,即事先确定变量的大小,维数。这一类的函数有zeros、on 
es、cell、struct、 
repmat 等。 
b、当要预分配一个非double型变量时使用repmat函数以加速,如将以下代码: 

A = uint8(zeros(100)); 
换成: 
A = repmat(uint8(0), 100, 100); 
c、当需要 扩充一个变量的大小、维数时使用repmat函数。 

3、a、优先使用matlab内建函数,将耗时的循环编写进MEX-File中以获 得加速。 
b、使用Functions而不是Scripts 。 

%%%%%%%%%%%%%%%%%%%%%% 
三、 绝招 

你也许觉得下面两条是屁话,但有时候它真的是解决问题的最好方法。 
1、改用更有效的算法 
2、采用Mex技 术,或者利用matlab提供的工具将程序转化为C语言、Fortran语言。 

关于如何将M文件转化为C语言程序运行,可以参阅本版帖 子:“总结:m文件转化为c/c++ 
语言文件,VC编译”。 

junziyang 2004-10-25 01:00 
Re: 【转贴】加速matlab运行的三重境界 

以上绝招是针对R13及以前版本的。从R14开始,Mathworks声称已经完成所有内建 函数及工具箱的加速,Mex技术对提高程序运行速度已无用,其作用只是可以增强程序的可移植性而已。我试验过,确实如此,有时甚至会出现转换后的函数运行 速度反而变慢的现象!其他绝招还是有效的。
 
这里只介绍 加快MATLAB程序编程效率的建议,其他内容请参见作者著作。

因为 MATLAB 语言是一种解释性语言,所以有时 MATLAB 程序的执行速度不是很理想。这里将依照作者十多年的实际编程经验给出加快 MATLAB 程序执行速度的一些建议和体会。

尽 量避免使用循环:循环语句及循环体经常被认为是~MATLAB 编程的瓶颈问题。改进这样的状况有两种方法:
(1) 尽量用向量化的运算来代替循环操作。我们将通过如下的例子来演示如何将一般的循环结构转换成向量化的语句。
〖例3.19〗考虑下面无穷级数求和问 题:

如果我们只求出其中前有限项,比如 100,000 项之和 (要精确地求出级数的和,无需求 100000 项,几十项往往就能得出满意的精度。这里主要是为了演示循环运算向量化的优越性。),则可以采用下面的常规语句进行计算
>> tic, s=0;
for i=1:100000, s=s+(1/2^i+1/3^i); end, s,toc
s =
1.5000
elapsed_time =
1.9700

如果采用向量化的方法,则可以得出下面结果。可以看出,采取向量化的方法比常规循环运算效率要高得多。
>> tic, i=1:100000; s=sum(1./2.^i+1./3.^i), toc
s =
1.5000
elapsed_time =
0.3800

(2)在必须使用多重循环的情况下,如果两个循环执行的次数不同,则建议在循环的外环执行循环次数少的,内环执 行循环次数多的。这样也可以显著提高速度。

〖例3.20〗考虑生成一个 5x10000 的 Hilbert 长方矩阵,该矩阵的定义是其第 i 行第 j 列元素为 h_{i,j}=1/(i+j-1)。我们可以由下面语句比较先进行 i=1:5 的循环和后进行该循环的耗时区别,其效果和前面分析的是一致的。
>> tic
for i=1:5
for j=1:10000
H(i,j)=1/(i+j-1);
end
end
toc
elapsed_time =
8.6800
>> tic,
for j=1:10000
for i=1:5
J(i,j)=1/(i+j-1);
end
end
toc
elapsed_time =
25.7000 

大型矩阵的预先定维
给大型矩阵动态地定维是个很费时间的事。建议在定义大矩阵时,首先用 MATLAB 的内在函数,如zeros() 或 ones() 对之先进行定维,然后再进行赋值处理,这样会显著减少所需的时间的。

再 考虑例 3-20 中的问题,如果输入下面的命令
>> tic
H=zeros(5,10000);
for i=1:5
for j=1:10000
H(i,j)=1/(i+j-1);
end
end
toc
elapsed_time =
1.0400
则采用预先定维的方法,再结合向量化的方法,我们可以给出下面的 MATLAB 语句。
>> tic
H=zeros(5,10000);
for i=1:5
H(i,:)=1./[i:i+9999];
end
toc
elapsed_time =
0.060

可见,预先定维后,所需要的时间显著地减少了。可以看出,同样一个问题,由于采用了有效的措施,所需的时间就可以 从 25.7 秒减少到 0.06 秒,亦即效率提高了 428 倍。 

对二重循环这样的特殊问题,我们还可以使用 meshgrid() 函数构造两个 5x10000 矩阵 i 和 j,从而直接得出 H 矩阵,更进一步地加快速度。
>> tic, [i,j]=meshgrid(1:5,1:10000); H=1./(i+j-1); toc
elapsed_time =


优先考虑内在函数
矩阵运算应该尽量采用 MATLAB 的内在函数,因为内在函数是由更底层的编程语言 C 构造的,其执行速度显然快于使用循环的矩阵运算。 

采用有效的算法
在实际应用中,解决同样的数学问题经常有各种各样的算法。例如 求解定积分的数值解法在 MATLAB
中就提供了两个函数 quad() 和 quad8(),其中后一个算法在精度、速度上都明显高于前一种方法。所以说,在科学计算领域是存在“多快好省”的途径的。如果一个方法不能满足要求,可 以尝试其他的方法。 

应用 Mex 技术
虽然采用了很多措施,但执行速度仍然很慢,比如说耗时的循环是不可避免的,这样就应该考 虑用其他语言,如 C 或 Fortran 语言。按照 Mex 技术要求的格式编写相应部分的程序,然后通过编译联接,形成在 MATLAB 可以直接调用的动态连接库 (DLL) 文件,这样可以显著地加快运算速度。有关 Mex 技术及其应用的详细内容可参见第 7 章。
 

最近刚在使用,到网上找了一些东西,希望能与大家一起分享!!

转载自研学论坛:http://bbs.matwav.com/post/view?bid=12&id=87986&sty=3&keywords=%BC%D3%BF%ECMatlab%B3%CC%D0%F2%B1%E0%B3%CC%D0%A7%C2%CA%B5%C4%BD%A8%D2%E9

http://zkong.luojia.net/CAE/pages/1051936490/

0 0
原创粉丝点击