matlab需要多⼤运存_提⾼matlab运⾏效率
⽤过Matlab的⼈都知道,Matlab是⼀种解释性语⾔,存在计算速度慢的问题,为了提⾼程序的运⾏效率,matlab提供了多种实⽤⼯具及编码技巧。
1. 循环⽮量化
Matlab是为⽮量和矩阵操作⽽设计的,因此,可以通过⽮量化⽅法加速M⽂件的运⾏。⽮量化是指将for循环和while循环转换为等价的⽮量或矩阵操作。下⾯给出⼀个循环的例⼦:
i=0;
for n = 0:0.1:1000
i=i+1;
y(i)=cos(n);
end
那么我们可以⽮量化为:
n= 0:0.1:1000;
y=cos(n);
我们可以⽤tic和toc函数来查看上述各代码运⾏的时间,采⽤for循环的程序0.39秒(具体时间和计算机配置有关),⽽⽮量化后⼏乎耗时为0。
2. 给数组或矩阵预分配内存
特别是使⽤⼤型数组或矩阵时,Matlab进⾏动态内存分配和取消时,可能会产⽣内存碎⽚,这将导致⼤量闲置内存产⽣,预分配可通过提前给⼤型数据结构预约⾜够空间来避免这个问题。
3. ⽤函数代替脚本⽂件
因为每次调⽤MATLAB的脚本⽂件都需要将不必要的中间变量加载到内存中,每执⾏⼀次,就加载⼀次。函数在调⽤时被编译成了伪代码,只需要加载到内存⼀次。当多次调⽤同⼀个函数时会运⾏快⼀些。因此尽量多使⽤函数⽂件⽽少使⽤脚本⽂件,也是提⾼执⾏效率的⼀种⽅法。
4. ⽤Mex⽂件编写循环代码
Matlab提供了与C和C++的接⼝,那么我们可以在⽤C或C++语⾔编写耗时的循环代码,然后通过接⼝程序在Matlab中转换成dll⽂件,这就是我们所要的Mex⽂件,通过这种⽅法可以极⼤地提⾼计算速率。
1.尽量避免使⽤循环结构
MATLAB变量的基本类型是矩阵,当对矩阵的每个元素循环处理时,运算速度很慢。因此编程时应尽量把数组和矩阵看作⼀个整体来进⾏编程,⽽不是像其他的程序设计语⾔那样,使⽤循环结构对矩阵的元素循环进⾏处理。利⽤MATLAB提供的⽤于⽮量化操作的函数,把循环⽮量化,这样既可以提⾼编程效率,也可以提⾼程序的执⾏效率。下⾯给出⼀个循环的例⼦:
i=0;
for n = 0:0.1:100
i=i+1;
y(i)=cos(n)
end
上述程序段把数组中的每个元素都进⾏函数值计算,这样会耗费⼤量的运算时间,我们可以把数组看作⼀个整体来处理,计算函数值,可以修改这个程序段如下。
n = 0:0.1:100;
y = cos(n)
通过使⽤MATLAB专门提供的测试程序运⾏时间的函数,可以发现,把数组看作⼀个整体,进⾏操作后,执⾏效率提⾼约300倍。
另外,在必须使⽤多重循环的情况下,建议在循环的外环执⾏循环次数少的,内环执⾏循环次数多的,这样也可以显著提⾼程序执⾏速度。
2.在使⽤数组或矩阵之前先定义维数
MATLAB中的变量在使⽤之前不需要明确地定义和指定维数。但当未预定义数组或矩阵的维数时,当需赋值的元素下标超出现有的维数时,MATLAB 就为该数组或矩阵扩维⼀次,这样就会⼤⼤降低程序的执⾏效率。因此,在使⽤数组或矩阵之前,预定义维数可以提⾼程序的执⾏效率。
3.对矩阵元素使⽤下标或者索引操作
在MATLAB中,矩阵元素的引⽤可⽤两个下标来表⽰。例如:A(i,j)
表⽰矩阵的第i⾏第j列的元素;A(1:k,j)表⽰矩阵A的第j列的前k个元素;A(:,j)
表⽰矩阵的第j列的所有元素。求矩阵A的第j列元素的平均值的表达式为mean(A(:,j))。
4.尽量多使⽤函数⽂件少使⽤脚本⽂件
因为每次调⽤MATLAB的脚本⽂件都需要将不必要的中间变量加载到内存中,每执⾏⼀次,就加载⼀次。函数在调⽤时被编译成了伪代码,只需要加载到内存⼀次。当多次调⽤同⼀个函数时会运⾏快⼀些。因此尽量多使⽤函数⽂件⽽少使⽤脚本⽂件,也是提⾼执⾏效率的⼀种⽅法。
5.在必须使⽤循环时,可以考虑转换为C-MEX
当必须使⽤耗时的循环时,可以考虑将循环体中的语句转换为C-MEX。C-MEX是将M⽂件通过MATLAB的编译器转换为可执⾏⽂件,是按照
MEX
技术要求的格式编写相应的程序,通过编译连接,⽣成扩展名为.dll的动态链接库⽂件,可以在MATLAB环境下直接执⾏。这样,循环体中的语句在执⾏时不必每次都解释(interpret)。⼀般来说,C-MEX
⽂件的执⾏速度是相同功能的M⽂件执⾏速率的20~40倍。编写C-MEX不同于M⽂件,需要了解MATLAB C-MEX规范。幸运的是MATLAB提供了将M⽂件转换为C-MEX的⼯具。
6.内存优化
MATLAB在进⾏复杂的运算时需要占⽤⼤量的内存。合理使⽤内存和提⾼内存的使⽤效率,可以加快运⾏速度,减少系统资源的占⽤。
7.内存管理函数和命令
(1)Clear variablename:从内存中删除名称为variablename的变量。
(2)Clear all:从内存中删除所有的变量。
(3)Save:将指令的变量存⼊磁盘。
(4)Load:将save命令存⼊的变量载⼊内存。
(5)Quit:退出MATLAB,并释放所有分配的内存。
(6)Pack:把内存中的变量存⼊磁盘,再⽤内存中的连续空间载回这些变量。考虑到执⾏效率问题,不能
在循环中使⽤。
8.节约内存的⽅法
(1)避免⽣成⼤的中间变量,并删除不再需要的临时变量。
(2)当使⽤⼤的矩阵变量时,预先指定维数并分配好内存,避免每次临时扩充维数。
(3)当程序需要⽣成⼤量变量数据时,可以考虑定期将变量写到磁盘,然后清除这些变量。
当需要这些变量时,再重新从磁盘加载。
(4)当矩阵中数据极少时,将全矩阵转换为稀疏矩阵。
提⾼MATLAB程序效率的⼏点原则,这些都是俺在这两年中参加四次数模编写⼤量m程序总结的经验,加之⽹上很多英雄也是所见略同。
1.“计算向量、矩阵化,尽量减少for循环。”[/B]
因为MATLAB本来就是矩阵实验室的意思,他提供了极其强⼤⽽灵活的矩阵运算能⼒,你就没必要⾃⼰再⽤⾃⼰编写的for循环去实现矩阵运算的功能了。另外由于matlab是⼀种解释性语⾔,所以最忌讳直接
使⽤循环语句。但在有些情况下,使⽤for循环可以提⾼程序的易读性,在效率提⾼不是很明显的情况下可以选择使⽤for循环。
⼝说⽆凭,下⾯是利⽤tic与toc命令计算运算所⽤时间的⽅法,测试两种编程的效率。需要说明的是没有办法精确计算程序执⾏时
间,matlab帮助这样写到“Keep
in mind that tic and toc measure overall elapsed time. Make sure
that no other applications are running in the background on your
system that could affect the timing of your MATLAB
programs.”意思是说在程序执⾏的背后很可能有其他程序在执⾏,这⾥涉及到程序进程的的问题,m程序执⾏的过程中很可能有其他进程中断m程序来利⽤cup,所以计算出来的时间就不仅是m程序的了,在这种情况下我把那些寄点去掉,进⾏多次计算求他的平均时间。
n = 100;
A(1:1000,1:1000) = 13;
C(1:1000,1) = 15;
D(1:1000,1) = 0;
for k = 1:n
D(:)
= 0;
tic
for
i = 1:1000
for
j = 1:1000
D(i)
= D(i) + A(i,j)*C(j);
end
end
matlab数组赋值t1(k)
= toc;
%------------------
D(:)
= 0;
D
= A*C;
t2(k)
= toc;
end
u = t1./t2;
u(u<0) = [];
plot(u)
p = mean(u)
t1、t2分别代表⽤for循环编程和矩阵化编程计算矩阵乘向量所⽤时间,u代表时间的⽐值。u(u<0) = [];是认为t1不可能⼩于t2,所以去掉不可能出现的情况。然后画出图形计算平均值。
经多次试验结果⼤致相同,其中⼀次结果如下:
p =
9.6196
------------t1时间是t2的⼗倍左右。
2.“循环内⼤数组预先定义--预先分配空间”[/U]
这⼀点原则是极其重要的,以⾄于在编写m程序时编辑器会给出提⽰“'ver' might be growing inside a loop.Consider prealloacting for speed.”
clear
n = 50;
m = 1000;
for k = 1:n
A
= [];
tic
A(1:m,1:m)
= 3;
for
i = 1:m
A(i,i)
= i;
end
t1(k)
%------------
A
= [];
tic
for
j = 1:m
A(j,j)
= j;
end
t2(k)
= toc;
end
t2(t1>10^9) = [];
t1(t1>10^9) = [];
plot([t1;t2]')
t1、t2分别表⽰预先分配空间和循环中分配空间的时间,下图上⾯⼀条t2、下⾯t1
3.“尽可能利⽤matlab内部提供的函数”[/U]
因为matlab内部提供的函数绝对是各种问题的最优算法,那写程序都是他们⼤师级⼈物写出来的,程序应该说相当⾼效,有现成的为什么不⽤那! 这个原则就不⽤实际的程序测试了。
关于MATLAB程序提速的问题,可以参考⽹上很多智者的⽂章,都⽐较经典。也可以看看我的上⼀篇⽂章,和⽹上⼤部分帖⼦有点不同,我是以实际的测试程序作为依据对如何提⾼MATLAB程序速度进⾏介绍的。 这⾥我再补充⼏点⼤家需要注意的。下⾯是我在国内⼀个⽐较出名的论坛看到的关于m程序提速的帖⼦,开始还真以为他们谈论的都应该遵循。(尽信书不如⽆书)
帖⼦的⼀部分这样说道:“当要预分配⼀个⾮double型变量时使⽤repmat函数以加速,如将以下代码:
A = int8(zeros(100));
换成:
A = repmat(int8(0), 100, 100);”
凡事不能只凭⾃⼰的感觉,没有⼀点实际的例⼦,对于权威我们还要有挑战精神那,就不⽤说现在还不是经典的观点了。下⾯是我写的测试程序,我本来是想得到这位⽹友⼤哥的结果,但是实事不是我们想象的那么简单。
n = 100;
m = 1000;
for k=1:n
tic
A
= int8(ones(m));

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。