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

加速Matlab编程指南(CUDA实现)

本教程适用于具有一定Matlab编程基础的读者。说是教程,更像是读书笔记,文中出现的内容多是笔者阅读以下资料的归纳和整理。主要参考的书籍及资料有:
《加速MATLAB编程指南CUDA实现》 赵地 清华大学出版社
《Matlab从入门到精通》
https://www.mathworks.com
MATLAB正版下载

为什么使用MATLAB

众所周知,当前机器学习,深度学习的代码实现往往都是在python上。笔者为什么非要在MATLAB上编写代码呢,主要原因有以下几点:

  1. 配置简单 ,MATLAB更像是一款应用软件。环境配置和代码编译由程序后台自动执行,只用编写代码并执行即可,
  2. 语言简单,MATLAB更注重算法,而不是代码实现。这里的算法是指按照人类思维方式,系统而又完整地描述解决问题的方案,因此按照算法编写的MATLAB程序在语言上,与算法本身具有很大的相似性。在MATLAB实现某种算法,只需创建矩阵和对矩阵进行运算;
  3. 可视化高 ,往往一些数学运算的代码实现是繁琐的,例如:计算FFT(快速傅里叶变换),MATLAB提供了fft()函数,工程师们已经将该函数的底层代码优化到了尽可能的高效。因此我们无需自己设计代码和对其修改,拿来即用。除此之外还需许多丰富的工具箱,和简洁明了的图形化操作界面;
  4. 最后,其实最主要的原因还是因为笔者长期处在高校,学术界使用MATLAB的情况颇多。笔者科研中常常使用MATLAB,也遇到诸多麻烦,结合了自己使用MATLAB的情况,希望能够分享给大家一些使用MATLAB的技巧。

总结就是:MATLAB更注重算法的研究,而不是代码的实现。作为初学者,使用MATLAB学习,能够避免繁杂的编程语言学习,将更多的时间放在算法的数学思考上面。

MATLAB程序的性能评估

MATLAB程序的性能评估(profiling)是指对MATLAB程序的空间复杂度(space complexity)和时间复杂度(time complexity)进行分析。不过,最简单粗暴的方式,就是对MATLAB函数的运行时间进行分析,自然越快越好。

运行程序前的性能评估

运行MATLAB程序之前,程序员首先希望知道当前计算机的性能。MATLAB的 bench() 函数的功能是运行MATLAB基准程序,测试MATLAB在本计算机上的性能。
在命令窗口输入 bench( )

运行程序后的性能评估

在运行一段程序后,如果能够获得程序的运行时间,并再加以分析,将有利于对MATLAB程序进行优化。
MATLAB的tic()/toc()函数能够帮助我们快速地完成这个操作。 tic()toc() 函数一般配合使用。执行 tic() 函数时,程序将启动秒表计时器(stopwatch), toc() 函数将种植秒表计时器并读数, tic()toc() 函数的调用格式是:

tic
	% 程序中计时的部分;
toc
  • 程序员在度量CPU端MATLAB代码运行时间可以执行cputime()函数,该函数返回CPU运行时间,单位为秒。注意:与 tic()/toc() 函数不同之处在于, tic()/toc() 计算的是MATLAB程序运行的总的时间,包括CPU运行时间,内存读写时间等所有内容;而 cputime() 函数仅仅衡量MATLAB程序占用CPU的时间。

  • 程序员在度量CPU端MATLAB代码运行时间可以执行gputimeit()函数在一些GPU上运行的程序, gputimeit() 能为我们度量程序在GPU端的运行时间。

不管是在GPU端还是CPU端运行的函数,都可以timeit()函数度量。 timeit() 可以将被计时的函数调用多次并记录运行时间,返回多次运行时间的平均值。

最后MATLAB还为程序员提供了更简洁的图形化操作。仅需点击MATLAB图形化界面的 运行并计时(profiler)。程序执行完毕后将返回每一条命令、每一个函数耗时的细节。

本节涉及函数的参考连接:
bench()
tic()/toc()
timeit()
cputime
gputimeit()

基于多核处理器的MATLAB程序加速

MATLAB储存的数值数据是由矩阵(matrix)构成的。这也正式MATLAB的名字由来:Matrix Lab 矩阵实验室。

  • 标量:可以认为是1X1的矩阵,表示为: x x x
  • 向量(数组):可以认为是一维矩阵,表示为: ( x 0 x 1 x 2 ) \left(\begin{array}{ccccc}x_0\\x_1\\x_2\\\end{array}\right) x0x1x2
  • 矩阵:表示为: G = ( a 11 a 12 . . . a 1 n a 21 a 22 . . . a 2 n ⋮ a n 1 a n 2 . . . a n n ) G=\left(\begin{array}{ccccc}a_{11}&a_{12}&...&a_{1n}\\a_{21}&a_{22}&...&a_{2n}\\\varvdots\\a_{n1}&a_{n2}&...&a_{nn}\\\end{array}\right) G=a11a21an1a12a22an2.........a1na2nann
  • 张量:可以认为是多个矩阵的叠加,比较难表示,用的也少。

因为,为叙述方便,以后对所有的此类结构都用矩阵来描述。这些矩阵的创建方式也有多种,在任何一本入门级的教程都有详细的介绍,这里就不赘述了。
需要注意的是:MATLAB矩阵默认的数据类型为双精度型(double)。与C/C++等语言不同,MATLAB具有对不同类型数据进行转换的内在机制,这就使得不需要对数据类型严格的定义。

利用MATLAB内置函数更高效的运算

在MATLAB的程序的编制过程中,程序员经常需要对矩阵的性质判断。由于大多数MATLAB内置函数已经做了多核多线程的优化,通过利用如下内置函数,可以实现更高效的运算:

函数名称实现功能
isempty()检验矩阵是否为空集
isinf()检验矩阵每一个元素是否为Inf
isnan()检验矩阵每一个元素是否为NaN
isprime()检验矩阵每一个元素是否为素数
issorted()检验矩阵是否经过排序
ismember()检验一个元素是否被矩阵包含
histcounts()计算矩阵中某一数值区间的元素数量
prod()计算矩阵中元素的乘积
intersect()计算两个矩阵的交集
setdiff()计算两个矩阵的集合差
setxor()计算两个矩阵的集合对称差
union()计算两个矩阵的元素集合,每个元素只出现一次

例如:计算100的阶乘
利用prod()函数要比利用循环要高效得多

tic
	%循环计算阶乘;
	p = 1;
	for i=1:100
		p = p * i;
	end
toc

计算时间:

tic
	%prod()函数计算阶乘;
	a = 1:100;
	p = prod(a);
toc

计算时间:

向量化编程有利于矩阵高效运算

所谓“向量化编程”,即尽量使用矩阵运算来代替使用for循环。这要求使用者要较为熟练高等代数的内容。
向量化编程更快同样是因为MATLAB矩阵运算已经做了多核多线程的优化,
例如:计算不同 x x x 下多项式的值的和:
对于 P ( x ) = 1 + 2 x + 3 x 2 + 4 x 3 + 5 x 4 + 6 x 5 P(x)=1+2x+3x^2+4x^3+5x^4+6x^5 P(x)=1+2x+3x2+4x3+5x4+6x5
x = 1 , 2 , 3 , . . , 50 x=1,2,3,..,50 x=1,2,3,..,50 时,所有 P ( x ) 的 和 P(x)的和 P(x)

tic
	% 循环计算;
	s = 0;
	for i=1:50
		p = 1 + 2*i + 3*i^2 + 4*i^3 + 5*i^4 + 6*i^5;
		s = s + p;
	end
toc

计算时间:

tic
	% 向量化编程;
	i = 1:50';
	x = [i^0 i^1 i^2 i^3 i^4 i^5];
	s = sum(x*[1 2 3 4 5]');
toc

计算时间:

矩阵运算中,MATLAB要要求参与的数组应具有相同的大小。

  • 如果数组大小不一致,采用 repmat() 或者 repelem() 将尺寸一致化。
  • 如果矩阵维度不一致,则用 reshape() 将尺寸一致化。
  • repmat()repelem()reshape() 计算开销、内存开销大。bsxfun()cellfun()arrayfun()

例如在深度学习工具箱DeepLearnToolbox的卷积神经网络(Convolutional Neural Network, CNN)中,训练数据进行归一化的代码为:

funtion x = normalize(x, mu, sigma)
	x = bsxfun(@minux, x, mu);
	x = bsxfun(@rdivide, x, sigma);
end

计算softmax()函数的代码为:

funtion mu = softmax(eta)
	tmp = exp(3 * eta);
	denom = sum(tmp, 2);
	mu = bsxfun(@rdivide, tmp, denom);
end
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值