Loren在Matlab的艺术上

将想法转化为matlab

制作MATLAB代码的主要案例研究更快

今天我想欢迎一位客人博客, Mike Croucher. ,最近在支持学术计算研究的长期职业生涯后,最近加入了Mathworks作为客户成功工程师。万博1manbetx

介绍

我的大多数职业生涯都致力于与科学家和工程师合作,以改善他们的计算工作流程。有很多事情可以做到,包括鼓励使用版本控制或使用 单元测试 但是,到目前为止,最常见的要求 “你能让我做得更快的事情吗?”
超过二十年的被问到这个简单的问题让我探索了许多技术计算领域,如并行计算,数值分析, HPC和云计算 GPU计算 ,数学优化, 自动分化 和多种语言只有几个。
在其核心,使程序更快地探讨了两个简单的步骤。
  1. 找出究竟是什么慢。
  2. 尝试不同的东西,看看它是否在仍然提供正确的答案
正如你想象的那样,上面隐藏了一个复杂的世界。“尝试不同的东西”可能意味着使用语言特征来优化我写入的算法,尝试并行甚至切换到完全不同的算法的Althogether。我通常向第2点添加一个额外的约束,这是“尽可能少的努力”,因为我从根本上懒惰。
Matlab的探查器,哪个 最近收到了界面大修 要提供代码执行时间的火焰图视图,有助于处理第一点。探索探查器将为博客宽容的内容提供丰富的缝线,就像探索所有的博客 算法性能增强 我们从发布到发布。
谢谢 MATLAB执行引擎 (以前讨论过这个博客 这里 这里 ) 和 各种其他优化 ,现代MATLAB比以往任何时候都快速,如下图所示,我们在这一领域不断改进。
当然,当我们需要优化我们的速度时,我希望能够分享最近在内部讨论的示例。

不要害怕弯帽

灵感来自这篇文章 ,同事在Matlab中写下以下内容来计算素数。
类型mycountprimes.m.
%计数有多少次近摄的次数且包括max_n函数res = mycountprimes(max_n)res = 0;对于i = 2:max_n如果myisprime(i)res = res + 1;结束端末期%函数检查n是prime函数结果= myisprime(n)如果n <= 1结果= false;返回端Q =楼层(SQRT(N));对于i = 2:q如果mod(n,i)== 0结果= false;返回结束最终结果= true;结尾
numprimes = mycountprimes(1000000)
numprimes = 78498.
这个代码在循环上非常沉重 - 正是我训练的那种东西,以避免在我早期的matlab天,但由于执行引擎,它不会太糟糕。(看 最近的帖子有关循环速度的更多信息 在matlab)
f = @()mycountprimes(1000000);
OriginalSpeed = Timeit(F)
OriginalSpeed = 3.7878.
即便如此,我们也有很多事情可以努力加快这段特定的代码。我们可以利用循环的每一次迭代的事实 mycountpimes. 是独立的,并使用并行 议案环形 。这很容易做,但在计算资源方面可能很重。一旦你意识到你可以利用 议案 ,尝试使您的问题抛出尽可能多的CPU核心,这变得很诱人。这几天我最喜欢做这一点的方法就是开枪 云中心集群 并加速核心计数,如此有意义。

改变摩擦地面

探查器表明我在线中花了很多时间
如果mod(n,i)== 0
所以一个方法是问 “我们可以重写那条线吗? 。这并不总是很明显哪种替代方案可能工作,所以我经常弄清楚不同的方式来做一些事情并试一试。写表达的另一种方法 mod(n,i)== 0 地板(n / i)== n / i 事实证明要快得多!我这样做了 Floormycountprimes. 函数,检查它给出了正确的结果,并表明它确实更快。
numprimes = floormycountprimes(1000000)
numprimes = 78498.
f = @()floormycountprimes(1000000);
地板= Timeit(F)
楼层距= 0.5296

尝试整数算法的整数类型

默认情况下,MATLAB中的所有数字都是浮点类型 双倍的 这对于许多数值计算非常重要,但在这里我们正在处理纯粹的整数算法。它有时可以支付股息,以使这是在代码中的明确,这是其中一个时代!事实证明 摩擦 在处理浮点数时,功能必须做更多的工作,而是对于该特定示例的严格必需。作为程序员,我知道我的算法基于完全整数,所以我可以切换到使用 UINT32. 对于一些变量。也就是说,我改变了主循环 myisprime.
Q =楼层(SQRT(N));
n = uint32(n);
为了i = uint32(2):q
如果mod(n,i)== 0
结果= false;
返回
结尾
结尾
这允许MATLAB使用专业和更快的版本 摩擦 功能自现在知道我们正在处理整数而不是双打。
我这样做了 uint32myisprime. 在此帖子末尾定义的功能,并通过uint32调用它 mycountpimes。 首先让我们检查结果与原始功能一致,然后时间
numprimes = uint32mycountprimes(1000000)
numprimes = 78498.
f = @()uint32mycountprimes(1000000);
uint32speed = timeit(f)
UINT32SPEED = 0.5660.
使用这种方法或基于楼层的方法,我们实现了相对较少的工作和技术的显着性能提升 议案 如果我们需要更多的速度,并行仍在桌面上。

matlab作为算法的存储库

最后,我们可以认识到,我们使用的基本算法来计算inches的不是最佳的,而不是使用不同的。将此置于极端,我们可以记住MATLAB是数字算法的存储库以及编程语言,因此找到直接解决我们想要解决的问题而不是滚动自己的语言的存储库。快速搜索文档揭示了 素瓜 返回次要次数的函数。我们生成此数组并按如下方式计算元素。
numprimes = numel(primes(1000000))
numprimes = 78498.
f = @()numel(primes(1000000));
buildInspeed = timeit(f)
BULLESEDPEED = 0.0029
为了我的目的超过足够快!

系统信息

如果您在自己的计算机上运行此脚本,则您将几乎肯定会给我带来不同的结果。使用 版本 功能和优秀 CPU INFO. 通过Ben Tordoff,这里是我的机器和MATLAB版本的详细信息。
版本info = ['matlab发布r'版本('-释放'
版本info =.'Matlab发布R2021A'
cpuinfo()
ans =.结构与字段:
名称:'英特尔(R)核心(TM)I7-8650U CPU @ 1.90GHz'时钟:'2112 MHz'Cache:'1024 KB'NumProcessors:4 Ostype:'Windows'Osversion:'Microsoft Windows 10 Pro'

你需要速度?

Matlab比以往任何时候都快,将来会继续变得更快。这与改进的硬件相结合,将帮助您回答比以往更大更复杂的问题。但是,总会有更多的时间我们需要更多。您认为Matlab加速技术有用,Matlab在Matlab中更快的是什么?让我们知道 这里
辅助功能
功能结果= floormyisprime(n)
%函数检查n是素数
如果n <= 1
结果= false;
返回
结尾
Q =楼层(SQRT(N));
为了我= 2:q
如果地板(n / i)== n / i
结果= false;
返回
结尾
结尾
结果=真实;
结尾
功能res = floormycountprimes(max_n)
%计数有多少次近摄的次数和包括max_n
res = 0;
为了i = 2:max_n
如果floormyisprime(i)
Res = Res + 1;
结尾
结尾
结尾
功能结果= uint32myisprime(n)
%函数检查n是素数
如果n <= 1
结果= false;
返回
结尾
Q =楼层(SQRT(N));
n = uint32(n);
为了i = uint32(2):q
如果mod(n,i)== 0
结果= false;
返回
结尾
结尾
结果=真实;
结尾
功能RES = UINT32MYCOUNTPRIMES(MAX_N)
%计数有多少次近摄的次数和包括max_n
res = 0;
为了i = 2:max_n
如果Uint32myisprime(i)
Res = Res + 1;
结尾
结尾
结尾
版权所有2021 Mathworks,Inc。
|

注释

要发表评论,请点击这里登录您的MathWorks帐户或创建新的。