其实自己写matlab也有两年多时间了,虽然基本都能做到随用随会,满足基本所有的功能需求。但是作为一个通用计算平台,matlab其实有很多特定用途的工具箱,以及加速运算的小技巧,不同于一些语法或者函数用法的学习,这些小技巧可以称之为经验,需要不断积累。。

本文主要讲述matlab程序运行的加速与优化。
最近在做一些基于matlab的神经网络调参训练,需要尝试很多超参数的不同组合,所以在不同的机器上分别进行多种组合实验,加速算法验证。于是我发现,对于某些电脑加了内存条之后,反而运行速度变慢,感觉这种变慢本质上与matlab版本(我用的是matlab2018),电脑内存,cpu性能(运算能力与频率)都有关系。。如果搭配不好的话,还不如低版本的matlab与小内存的cpu的配置。。
下面分几种情况讲述matlab在运行中变慢的问题。

1、Matlab长时间运行越来越慢的问题

https://blog.csdn.net/u012140304/article/details/60868162

经常用matlab进行计算的人大概都有这种感觉:在程序刚开始运行时速度很快,但是跑着跑着就变慢了而且是越来越慢。
实际我觉得这个问题和CPU没有关系,主要和内存有关系。具体问题的根源也不清楚。不过这里有两个建议可以减缓这种问题:

  • 将程序分解成多次运行,尽量避免一次运行过长时间
  • 单次大内存消耗的matlab程序运行完将其关闭,下次运行时从新开启
  • 多次大内存消耗的matlab程序运行完时,有条件的话最好重启计算机
  • 将大内存消耗的matlab程序进行混合编程(包括将m文件转成C++可用的库,或者用C++/C写然后转成MATLAB可用的函数文件),如果可以直接用C/C++重新编写

其实matlab也是可以进行混合编程的,使用mex命令编译,结合C语言程序的速度优势,或者调用特定的运行库,并行线程,增加运行核心与频率,加大内存等等,甚至还可以借助CUDA代码进行GPU加速。。

以及:https://blog.csdn.net/renxingzhadan/article/details/70212948

问题
我用matlab做了一个优化的程序,调用comsol来进行计算,但是运行时间较长,我用实验室的服务器进行计算,但是一晚过后matlab的计算速度渐渐变慢,最后竟然停止了运算,请问各位大侠,这是个怎么个问题啊?

方案

好长时间没有上论坛了,刚看见你的回复,去年参加了研讨会,一个工程师告诉我说如果matlab运行时间过于长,可能每次运算所遗留的中间数据或者句柄(comsol和matlab link会在每次计算后保存句柄 heap),解决的方法是将matlab长时间的运行改为多个短时间的运行,在一次运行结束时保存好这次的数据,然后进行下一次的运算时将上次的保存数据载入即可,运行间隔的时候讲matlab重启或者将电脑重启一个,释放下内存中的数据。

其实可以用一些输出或者命令来进行运行时间的监测
linux下:据说linux下可以直接安装只有命令行的matlab,没有gui。。使用profile viewer命令即可
更通用的,你可以使用程序tic;toc如下,参考:https://blog.csdn.net/kaever/article/details/71407127

2、matlab for循环过大程序运行慢解决方案

我们都知道,写for循环在逻辑上,以及运行速度上都是有讲究的,这需要权衡。。
对于大循环,一般要求尽量写在里面,小循环写在外面,好像吧。。
参考:https://blog.csdn.net/misayaaaaa/article/details/70477513

3、MATLAB2016a启动慢

注:最近遇到这个问题,特意查之解决,下面内容转自Matlab7中文站网站

首先介绍一下我自己使用的有效方法,一般matlab启动初始化很慢主要的原因是在找注册文件,一般是由于安装了MAC类的软件引起的,所以我按照下文提供的方法“在【目标】中,键入如下内容”$MATLAB\bin\win32\MATLAB.exe” -c “””,我在快捷方式里面目标路径中键入:“C:\Program Files\MATLAB\R2009b\bin\win32\MATLAB.exe” -c “C:\Program Files\MATLAB\R2009b\bin\win32\lic_standalone.dat”,即解决了这个问题,感谢网友无私的分享精神。注意上面路径中lic_standalone.dat是自己的许可文件,换换就可以了!

Matlab随着版本的升级体积越来越大,带来的问题就是启动速度也越来越慢,下面就我注意到的几个影响MATLAB启动速度的问题集中和大家分析下解决办法。

转载链接:http://blog.sciencenet.cn/blog-55488-970437.html

对于最近matlab2016/2017/2018,据说2019都出来了。。这种越大越大的matlab,有些工具箱可能还需要重装,或者付费。。感觉去加速它的启动,没有必要,或者也加速不了太多。。


这里列一下几个加速matlab程序运行的通用方法:

一、 遵守Performance Acceleration的规则
关于什么是“Performance Acceleration”请参阅matlab的帮助文件。我只简要的将
其规则总结如下7条:
1、只有使用以下数据类型,matlab才会对其加速:logical,char,int8,uint8,int16,uint16,int32,uint32,double
而语句中如果使用了非以上的数据类型则不会加速,如:numeric,cell,structure,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, which means it is designed
for vector and matrix operations. You can often speed up your M-file code by using vectorizing algorithms that take advantage of this design. Vectorization 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、ipermute、permute、reshape、squeeze、any、find、logical、prod、shiftdim、sub2ind、cumsum、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 Accelerator instead of vectorizing.”。何去何从,自己把握。
b、在必须使用多重循环时下,如果两个循环执行的次数不同,则在循环的外环执
行循环次数少的,
内环执行循环次数多的。这样可以显著提高速度。

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

A = int8(zeros(100));

换成:

A = repmat(int8(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编译”。


参考:
https://blog.csdn.net/xiaotianlan/article/details/51395542
https://blog.csdn.net/pursh0000/article/details/51314209

Profile(分析)

这个命令的话,自然是在linux下。

在加速你的matlab程序之前,你需要知道你的代码哪一部分运行最慢。matlab提供个简单的机制,让你能够知道你
的代码的某一部分运行所占用CPU时间。通过在代码段开始添加tic,及在结束添加toc;matlab就能计算出这一代
码段的运行时间。

Tic和toc方法存在两个问题:

(1)显示的时间是运行时间“wall clock”。这个时间受你在运行你的代码时,你的计算机是否同时运行其它别的程

序。

(2)你需要不断地压缩计时范围来查找你代码运行最慢的位置。

一个最好的方法是利用matlab 内嵌的代码分析器。在你的程序前面通过添加命令profile on;及在程序结束添加

profile viewer;并运行你的程序。当程序正常运行结束时,代码分析器窗口将弹出,并显示分析结果。它包含的信息

有:

Function Name :函数名;

Calls :函数被调用次数;

Total Time :执行该函数的CPU总用时,包含任何其它被它调用的函数的CPU时间。

Self Time :执行该函数的CUP总用时,不包含任何其它被它调用的函数的CUP时间。

Total Time Plot :时间用时的曲线图。

以上信息可进行各种排序和详细查看。

注意:当你完成你的代码分析后,请删除profile on和profile viewer,因为嵌入代码分析器会使用的程序运行变慢。

标准提示

☆有问题找帮助文档。学会使用帮助文档,学会针对待解决的问题检索文档资料。

☆性能

查看MATLAB->Programming->Improving Performace and Memory Usage;或MATLAB->Programming

Fundamentals->Performace->Techniques for Improveing Performace。

多线程

如果你使用的是多核心的计算机,那么你就可以让Matlab同时运行多个线程,Matlab程序中一些底层的函数

(Low-level function)就有可能采用并行计算的方法。打开多线程的方法:File->Preferences选择General->

Multithreading。扣选Enable multihread computation box。如果不限制使用核心的数目,可以保留使用Automatic。

注意:Matlab R2008a之前的版本在AMD处理器上是不支持多线程的。

向量化循环

Matlab的运算是针对向量(矢量)和矩阵进行设计的,因此它在向量和矩阵上的运算速度比采用循环的方式更快。

例如:

index=0;for time=0:0.001:60;index=index+1;waveForm(index)=cos(time);end;

采用以下代码可加快速度。

Time=0:0.01:60;waveForm=cos(time);

一些有用的,可用于代替循环的函数:

any();size();find();cumsum();sum();

矢量化编程很重!!!

向量预分配

Matlab采用内存中一块连续的空间来存储向量和矩阵数据,而不是用链表。这就意味着你每给向量或矩阵增加一元

素,Matlab需要寻找一块足够大的内存区域来存储这个扩大后的向量或矩阵,然后复制现有的数据到新的内存区

域。在循环中增加向量或矩阵元素的元数是允许的,但并不是明智之举,而应该是一次性分配向量或矩阵的大小,

或一次性重定义尺寸。

Results=0;for index=2:1000;results(index)=results(index-1)+index;end

上述代码将比以下代码速度慢:

results=zeros(1,1000);for index=2:1000;results(kindex)=results(kindex-1)+index;end;

注意:当你需要用zeros()来创建一个指定数据类型的向量或矩阵时,你可以使用创建参数来指定类型,而不是“重

铸”。results=int8(zeros(1,1000));将创建一个有1000个元素的double型零向量,然后把它转换成int8类型。如果我

们使用results=zeros(1,1000,‘int8’); Matlab将支持建立1000个int8类型的向量,在创建可实现性及速度上将更具有

优势。

不要改变数据类型

Matlab为了能够支持宽松的数据类型(例如一个变量能够存储不同类型的数据,而不是指定它为特定的数据类

型),则Matlab除了存储单纯的数据之外,还需要伴随数据存储一定数量的头信息(header),这就意味着需要内

存空间支存储数据类型,同时意味需要在数据类型转换上支付额外的计算机资源开支。

对于实数据使用 real…函数。

Matlab中的一些函数能够同时适用于实类型数据和复类型数据。如果你只使用实数据,那么采用特定的版本的,非

复数据函数,那么它运行的速度将变得更快。这些函数如:reallog(), realpow(),realsqrt()。

使用“短路”逻辑操作

Matlab的“短路”逻辑操作可以在判断条件达到充分条件后就停止计算处理,而不需要知道判断所有条件。例如:if(index>=3)&&(data(index)==5); 当index小于3时,第二个条件判断将不被处理,这样就少了去判断

data(index)==5)的时间,提高速度。

使用函数指针(句柄)

Matlab的一些函数使用函数名作用参数,常用一个变量支保存这个函数名字符串()如:func=‘tan’;然后用这个

变量作为函数的参数:fzero(func,0))。这种方法对于简单的函数调用是很好的,但是对于在循环中的重复调用就

存在两个问题:

(1)在每一个循环中,Matlab需要去搜索这个函数的路径(如tan),这需要花费时间。

(2)在循环过程中,路径可能会改变。这会保证在这一次循环中,某个版本的函数(如tan)被首先调用,而下一次

循环中这个版本的函数又被首先调用,最终会造成结果不一致。

解决的办法是使用文件指针(;或func=@sin),它能返回函数唯一的识别码。调用方式同上。

文件I/O

通常高级输入输出操作(load()和save())比一般的低级操作(fread()和fwrite())快。

☆内存使用

关于内存的使用可查看帮助文档Using Menory Efficently。可查与Memory Usage相关的信息。

一定记注:可以使用whos()来查看数据变量占有用的内存空间大小。

复制数组

当你复制一个数组时,Matlab开始只复制一个指向数据的一个指针,仅当你随后对任一版本进行修时,数据的复制

才真正的执行。这种操作包括数组作为函数参数进行传递的情况-作为值传递的参数传递,而不是作为参考的传

递。因此,你应该尽量避开对大数组进行小改动的操作。

数据不用时,释放内存

如果一个变量以后已经不再使用,那么你可以删除它clear VariableName;则这个小块的数据将可以重用。

注意:如果各变量在内存是连续的,则Matlab很容易重用这些大块的内存,因此最好是先建立大的变量,后再建立

小的变量,并且把它们组合起来。

结构体存储

上文已经提到,在Matlab中的变量包含有描述数据类型的头信息。对于一个结构体,则有一个描述整个结构的头信

息,及每个元素也分别有一个头信息。为了最小化地使用内存,我们应该小心地使用混合数据类型的数组和结构。

例如:

pixel.red(1:600,1:400)pixel.grn(1:600,1:400)pixel.blu(1:600,1:400)

则我们就需要存储4个头信息。而:

pixel(1:600,1:400).redpixel(1:600,1:400).grnpixel(1:600,1:400).blu

我们就有720001个头信息。

使用最小的合适的数据类型

为了减小内存使用量,对于特定的运算经常使用最小的数据类型。例如:

(1)对于虚部为零的数据,最好不要用complex去存储。

(2)如果精度足够,可采用single变量,而不用double。

(3)使用uint16来进行计数操作,它能存储值为0到65535。但它比默认的double型省一半的内存。

比如数组,元胞数组,结构体数组等等占用的内存空间就是很不一样的。。

使用稀疏矩阵

如果矩阵绝大多的数据为零值,可以把它转化成稀疏形式(使用sparse()函数)。它将只存储非零数据的数值和索

引。因为需要额外的存储数据的索引,因此只有二维数据的零值大约超过75%时,这种方法才是有效的,否则稀

疏形式反而需要更多的内存空间。

☆并行循环

如果从一个for循环的外部看,for循环满足以下标准:

(1)循环的计数是整数;

(2)每次循环都是独立的;

(3)计算循环先后顺序无关。

那么这个for循环就有可能可以替换成parfor循环(matlab2008a中可用优化算打开并行通信池:parfor循环包含于

matlabpool open 和matlabpool close之间)。

注意:打开一个并行工作池worker pool大约需要10-15秒钟,关闭一个工作池大概需要5秒钟。计算这个时间在

内,这个方法对于循环时间超过30秒的情况才是值得的。

matlab对内建函数与自定义函数也是有要求的,尽量不要重名,还有一样的文件名字,不同的文件后缀,也是有优先级索引顺序的。。


最后再从细节上进行把握吧,这也是用的较多的使用方法:
参考:
https://blog.csdn.net/gtx_tt/article/details/45367047
https://blog.csdn.net/weixin_34210740/article/details/85736527

(1)为矩阵变量预制内存而不是动态分配

慢:

for k = 2:1000

x(k) = x(k-1) + 5;

end

快:

x = zeros(1, 1000);

for k = 2:1000

x(k) = x(k-1) + 5;

end

在程序一开始就为所有大的矩阵变量预制存储单元。

(2)将循环语句改为向量形式

慢:

For ii=1:100

Square(ii)=ii^2;

End

快:

ii=1:100;

Square(ii)=ii^2;

!!!运行速度从慢到快依次为:for loop → for loop+preallocate with zeros function → vectorize

(3)逻辑数组可以用来将某个数组的子数组进行矢量化运算,避免循环,加快运行速度:

a=[1 2 3;4 5 6;7 8 9];

b=a>5

a(b)=sqrt(a(b)) %将a中大于5的数字求平方根

a(~b)=a(~b).^2  %将a中小于等于5的数字求平方

输出结果:

b =

0     0     0

0     0     1

1     1     1

a =

1.0000    2.0000    3.0000

4.0000    5.0000    2.4495

2.6458    2.8284    3.0000

a =

1.0000    4.0000    9.0000

16.0000   25.0000    2.4495

2.6458    2.8284    3.0000

(4)matlab profiler(运行和计时)

根据每行代码所耗费的时间分别改进。

2.生成随机数时,生成均匀分布的函数rand(x,y)的速度比生成其它分布的随机数的函数速度快的多,大概10倍左右;当要生成除正态和均匀分布以外的随机数时,自定义函数要比通用函数快的多,比如生成指数分布随机数,exprnd(1,1,20)速度是random(‘exp’,1,1,20)的40多倍。


最后,如果你不想从算法的角度去加速,而是想充分利用内存的话,可以看看这篇博客,主要是讲述如何扩大虚拟运行内存,以及最大化节省内存的的方法:
https://blog.csdn.net/wwwwws/article/details/42971623

matlab程序加速与优化相关推荐

  1. matlab程序加速与优化(系统全面)

    加速Matlab编程指南-持续更新 加速Matlab编程指南(CUDA实现) 为什么使用MATLAB MATLAB程序的性能评估 运行程序前的性能评估 运行程序后的性能评估 基于多核处理器的MATLA ...

  2. MATLAB实战系列(三十九)-matlab多目标优化之海洋捕食者算法

    前言 文中涉及代码可参见 matlab多目标优化之海洋捕食者算法 海洋捕食者算法(Marine Predators Algorithm, MPA)是Afshin Faramarzi等人于2020年提出 ...

  3. matlab多种分配方案_基于MATLAB的水资源优化分配问题动态规划解法

    基于 MATLAB 的水资源优化分配问题动态规划解法 摘要:介绍了动态规划的基本原理,针对水资源分配问题进行了 动态规划方法分析.针对具体问题采用逆序解法的表格法进行了计 算,然后用 matlab 编 ...

  4. matlab自带的优化工具箱,MATLAB 自带优化工具箱(optimization Tool)之遗传算法简述...

    MATLAB 自带优化工具箱(optimization Tool)之遗传算法简述 MATLAB 自带优化工具箱(optimization Tool)之遗传算法简述 MATLAB 自带优化工具箱(opt ...

  5. 【单目标优化求解】基于matlab增强型黑猩猩优化器算法求解单目标优化问题【含Matlab源码 2013期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[单目标优化求解]基于matlab增强型黑猩猩优化器算法求解单目标优化问题[含Matlab源码 2013期] 点击上面蓝色字体,直接付费下 ...

  6. Matlab 基于遗传算法优化的VMD信号去噪算法 创新点:基于样本熵作为适应度函数

    Matlab 基于遗传算法优化的VMD信号去噪算法 创新点:基于样本熵作为适应度函数 创新点2:基于信噪比作为适应度函数 提高信噪比 本人研究方向信号处理特征提取与故障诊断算法 ID:34506686 ...

  7. 【LSSVM分类】基于matlab灰狼算法优化LSSVM分类(多输入多分类)【含Matlab源码 1558期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[LSSVM分类]基于matlab灰狼算法优化LSSVM分类(多输入多分类)[含Matlab源码 1558期] 获取代码方式2: 付费专栏 ...

  8. 【Matlab多目标优化求解】遗传优化萤火虫算法求解多目标优化问题【含源码 1484期】

    一.代码运行视频(哔哩哔哩) [Matlab多目标优化求解]遗传优化萤火虫算法求解多目标优化问题[含源码 1484期] 二.matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 ...

  9. 【Matlab】智能优化算法_蜻蜓优化算法DA

    [Matlab]智能优化算法_蜻蜓优化算法DA 1.背景介绍 2.灵感 3.公式推导 3.1 勘探和开发操作 4.算法流程图 5.文件结构 6.伪代码 7.详细代码及注释 7.1 DA.m 7.2 d ...

最新文章

  1. matplotlib显示中文钥匙
  2. 哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现
  3. Winform ComboBox控件高亮显示
  4. 消息队列—主要消息中间件优势对比
  5. GridControl详解(三)列数据的格式设置
  6. RHEL4-SFTP配置
  7. The 2019 ICPC Asia Shanghai Regional Contest
  8. IF-ERRORLEVEL使用方法
  9. C++设计模式::装饰模式or代理模式or面向切片编程(AOP)
  10. 数据库性能Quest Performance Analysis Overview
  11. Ubuntu下c语言IDE学习
  12. 我见过最清晰的–理解梯度,散度,旋度
  13. Mushroom Classification(蘑菇分类数据集)
  14. Tmux(-yank,-cssh,-xpanes)使用指南
  15. 利用脚手架创建vue项目时报这个错误,哪位大神帮忙解答一下,实在是找到解决办法了。万分感谢
  16. EFR32MG裸机工程-2-LED
  17. cargo build failed: SSL connect error (schannel: failed to receive handshake, SSL/TLS connection fai
  18. 用Python操控手机APP攻略一
  19. 免费备份工具FreeFileSync
  20. Focus和SetFocus、GetFocus、LoseFocus

热门文章

  1. 计算机一级考试Office2007,计算机一级辅导:Office2007自动安装应答文件的制作
  2. 福利来啦!4月积分兑换JD卡渠道正式开启~
  3. H.266/VVC帧间预测技术学习:解码端运动矢量细化(Decoder side motion vector refinement, DMVR)
  4. CSS 文章段落样式
  5. 回顾SparkFun的micro:bit街机游戏机
  6. 分享一个 物联网大数据平台软件开发架构案例
  7. windows下DGL库cuda版本安装
  8. 运算放大器实现多路同向反向加减运算电路公式推导(二)
  9. 7.8.0版本知云文献翻译修改了PDF图标,改为旧版本图标的方法
  10. Unity灯光效果及设置详解