罗兰谈MATLAB的艺术

将想法转化为MATLAB

分页矩阵函数

今天的客座博主是Mary Fenelon,她是MathWorks的优化和数学产品营销经理。在今天的文章中,她描述了如何使用新的页面矩阵函数来简化代码并提高性能。
一个批处理的逐页矩阵乘法函数pagemtimes,以及逐页转置pagetranspose,和复共轭转置pagectranspose函数,在R2020b中添加到MATLAB®。新的函数使N-D数组作为密集矩阵的容器的操作更容易编写和更快地运行。
例如,如果A和B是3-D数组,并且您想要计算数组C是由A和B的前两个维度中包含的矩阵相乘形成的矩阵的集合,您可以用语句来实现C = pagemtimes(A,B)。
除了for循环到pagemtimesdlmtimesdlarray在深度学习工具箱和pagefungpuArray以及并行计算工具箱中的分布式数组。这些仍然可用,但现在可以为常规数组使用分页时间dlarray而且gpuArray
有时你只需要转置一个矩阵集合。现在你可以使用pagetranspose而不是交换

更容易

在本例中,要相乘的矩阵存储在4-D数组的前两个维度中
A = rand(4,5,6,7);
B = rand(2,5,6,7);
这个双重嵌套的for循环计算矩阵-矩阵乘积。下载188bet金宝搏
C1 = 0 (size(A,1),size(B,1),6,7);
p = 1:size(A,3)
q = 1:大小(A,4)
C1(:,:,p,q) = A(:,:,p,q)*B(:,:,p,q).';
结束
结束
使用pagemtimes,该代码可以简化为一个函数调用:
C2 = pagemtimes(A,“没有”B“转置”);
这当然更容易。字符串选项指定在乘法运算中使用第二个数组的逐页转置。pagemtimes隐式地将维度扩展到三个以上,以乘以所分页的矩阵的所有组合。

既然我已经说了更简单的,那么更快的呢?加速是否随着N-D数组的大小而变化?下面的循环遍历一组矩阵,其中第一个矩阵的行大小不同,但其他矩阵的维数是固定的。我画出时间和加速。
rng (“默认”);再现率%
N = 100;
K = 2;
P = 10000;
Mset = 10:10:100;
mSize = numel(mset);
tLoop = 0 (mSize,1);
tPage = 0 (mSize,1);
I = 1:数字(mset)
M = mset(i);
A = rand(m,n,p);
B = rand(n,k);
CPage = pagemtimes(A,B);
f = @()pagemtimes(A,B);
tPage(i) = timeit(f);
CLoop = loop times(A,B,m,k,p);
f = @()loopmtimes(A,B,m,k,p);
tLoop(i) = timeit(f);
结束
plotTimes (mset, n, p, k tPage tLoop);
Times图显示for循环花费的时间比pagemtimes.加速图显示了使用的好处pagemtimes当有很多小矩阵时是最大的,但即使是较大的值在美国,这种加速仍然是显著的。对于较小的矩阵的改进更为显著,因为被消除的开销占总时间的更大百分比。
我喜欢用时间而不是抽搐/toc有关计时(参见a以前的文章时间),尽管这需要将代码放入函数中进行计时。时间运行代码多次,并进行中值测量。这是中推荐的方法衡量代码的性能.即便如此,对于运行时间非常短的代码,比如当矩阵大小很小时,时间将无法返回准确的时间。在这种情况下,建议在循环中多次运行代码。
如果你对A和B的维度尝试不同的值,你会看到不同的加速。例如,当数组很大且只有几页时,就不会有太多内容,因为大部分工作都在实际的矩阵乘法中。由于难以测量小矩阵的时间,以及缓存和线程对大矩阵的影响,您可能还会看到一些不规则性。

更多的

可以为其他矩阵函数编写分页函数。我们应该先做哪些,它们将用于哪些应用程序?让我们知道在这里

辅助函数

函数Cloop =循环次数(A,B,m,k,p)
Cloop = 0 (m,k,p);
I = 1:p
Cloop(:,:,i) = A(:,:,i)*B;
结束
结束
函数plotTimes (mset, n, p, k tPage tLoop)
图(“位置”, 100100, 1200, 450)
T = tiledlayout(1,2);
nexttile
情节(mset tPage,‘*’);
持有
情节(mset tLoop,“o”);
传奇({“pagemtimes”“循环”},“位置”“西北”);
标题(“次”
包含(“米”
ylabel (“秒”
持有
nexttile
情节(mset tLoop. / tPage)
标题(“在for循环中加速页面时间”
包含(“米”
ylim([0,正])
标题str = sprintf('用A (m- %d- -%d)乘以B (%d- %d)', n, p, n, k);
标题(t, titleStr)
结束
The MathWorks, Inc.版权所有
|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。