【发布时间】:2016-11-15 14:54:46
【问题描述】:
旧标题:*R2016b 中的小矩阵乘法比 R2016a 慢得多* (更新见下文)
我发现 R2016b 中小矩阵的乘法似乎比 R2016a 小得多。这是一个最小的例子:
r = rand(50,100);
s = rand(100,100);
tic; r * s; toc
这在 R2016a 中大约需要 0.0012 秒,在 R2016b 中大约需要 0.018 秒。
创建一个人工循环以确保这不仅仅是一些初始开销或导致相同损失因子的东西:
tic; for i = 1:1000, a = r*s; end, toc
R2016a 大约需要 0.18 秒,R2016b 大约需要 2.1 秒。
一旦我使矩阵变得更大,比如r = rand(500,1000); 和s = rand(1000,1000),版本的行为相似(R2016b 甚至似乎快了约 15%)。任何人都知道为什么会这样,或者可以在另一个系统上验证这种行为吗?
我想知道它是否与新的算术扩展实现有关(如果此功能对小矩阵乘法有一些成本):http://blogs.mathworks.com/loren/2016/10/24/matlab-arithmetic-expands-in-r2016b/
更新
经过多次测试,我发现 MATLAB 版本之间没有这种差异(我很抱歉)。相反,它似乎与我的基础工作区中的内容有所不同......更糟糕的是,基础工作区中的变量类型。
我清理了一个巨大的工作区(其中有许多带有许多不同大小的小矩阵条目的大型单元阵列)。如果我清除变量并执行 r*s 的计时,我将获得比加载工作区之前更快的运行时间 (x10-x100)。
那么问题来了,为什么工作区中有变量会影响两个小变量的矩阵相乘呢?更重要的是,为什么某些类型的变量会显着减慢工作空间。
这是一个示例,其中工作区中单元格形式的大变量会影响矩阵乘法或两个不相关矩阵的运行时间。如果我将此单元格折叠成矩阵,效果就会消失。
clear;
ticReps = 10000;
nCells = 100;
aa = rand(50,100);
bb = rand(100, 100);
% test original timing
tic; for i = 1:ticReps, aa * bb; end
fprintf('original: %3.3f\n', toc);
% make some matrices inside a large number of cells
q = cell(nCells, nCells);
for i = 1:nCells * nCells
q{i} = sprand(10000,10000, 0.0001);
end
% the timing again
tic; for i = 1:ticReps, aa * bb; end
fprintf('after large q cell: %3.3f\n', toc);
% make q into a matrix
q = cat(2, q{:});
% the timing again
tic; for i = 1:ticReps, aa * bb; end
fprintf('after large q matrix: %3.3f\n', toc);
clear q
% the timing again
tic; for i = 1:ticReps, aa * bb; end
fprintf('after clear q: %3.3f\n', toc);
在这两个阶段中,q 占用大约 2Gb。结果:
original: 0.183
after large q cell: 0.320
after large q matrix: 0.175
after clear q: 0.184
【问题讨论】:
-
我怀疑只有 MathWorks 才能完全回答这个问题。但是,我建议使用
timeit来准确测量执行时间,尤其是对于小型计算。 -
我同意我的倾向是 MathWorks 是可以回答的主要人员。我刚才在 Matlab Central 上问过。感谢
timeit的建议——结果似乎与上面的tic/toc一致。 -
刚刚在 MacOS X 上尝试过,无法确认...
-
抱歉,我应该指定我在 Windows 上。感谢您查看 OSX!
-
我用新的发现更新了上面的问题。似乎乘法速度受到工作区中大单元格的影响:S
标签: matlab performance multiplication