一劳永逸地
我是跟我的长期的同事,迈克·裘槎加入MathWorks团队最近(耶!)。关于一些有趣的话题,其中一些可能一篇博客文章的好饲料。今天我想谈谈为循环。
嵌套循环
在我的旧的Fortran编程天(是的,长了),我认识到早期代码跑得更快,如果我安排我的嵌套对- - - - - -循环优化。在Fortran,如果我是计算矩阵的一个元素,这意味着确保我填充顺序的元素,这意味着循环在每一行1列,因为这就是Fortran (MATLAB)存储阵列。这不是如何存储在C数组。
我今天在MATLAB很好奇发生了什么如果我尝试运行嵌套循环在不同的订单。让我们看看!
让我们计算Ar, c = r * (r + c3) + 17
解决方案直接循环,内循环的行
当然我preallocate输出数组,基于“增大化现实”技术。
t = 0 (1、3);
n = 1000;
抽搐;
基于“增大化现实”技术= 0 (n, n);
[nrows, ncolumns] =大小(Ar);
为行= 1:nrows
为列= 1:ncolumns
基于“增大化现实”技术(行、列)=行*(行+列^ 3)+ 17;
结束
结束
t (1) = toc;
解决方案直接循环,内循环列
现在另一个订单。
抽搐;
Ac = 0 (n, n);
[nrows, ncolumns] = (Ac)大小;
为列= 1:ncolumns
为行= 1:nrows
交流(行、列)=行*(行+列^ 3)+ 17;
结束
结束
t (2) = toc;
矢量化的解决方案
当然,矢量化版本。
抽搐;
tmpr = (1: nrows)。';
Av = tmpr。* (tmpr + (1: ncolumns)。^ 3) + 17;
t (3) = toc;
分析
让我们确保他们也产生相同的结果。
areAnswerEqual = isequal (Ac, Ar, Av)
和执行时间呢?
t
顺序很重要
在MATLAB,使用嵌套为循环,明显的顺序循环问题从时间的角度来看。所以它是明智的命令他们知道数据存储列的列,如果你可以写你的算法。我没有显示效果可能是如果我们不preallocate输出矩阵。你可以试着自己。
尽管得到了很好的加速通过争吵嵌套循环,它仍然是通常更可取的,从速度的角度来看,尝试对代码进行向量化。注意,我使用隐式的扩张来计算Av。还要注意,你不会总是相同的速度比循环和等效矢量化版本之间的区别——它将在很大程度上取决于有多少工作进行了计算和产生多大的开销。
你的想法呢?
当使用MATLAB循环中,从速度的角度,最好是如果你可以设置循环元素是尽可能接近顺序访问。你可以看到从上面的小例子,运行列行提供优越的性能与运行。这是由于MATLAB存储阵列。
你遇到一个情况重新排序循环帮助你吗?让我们知道在这里。
版权2021年MathWorks公司。
评论
留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。