【发布时间】:2014-09-17 08:52:45
【问题描述】:
简介
我有一个算法可以循环数十亿(万亿)次并操作存储在 7 维 [10x10x10x10x10x10x10] 中的矩阵,我发现访问 7 维矩阵中的元素非常慢,我很好奇我运行了一些测试确定访问多维矩阵元素的性能。
假设
有人提醒我,MatLab 在后台使用线性索引,我的一个朋友说性能损失可能是由于将“正常”索引转换为后台Source 的线性索引。
测试方法
为了验证这个假设,我测试了使用线性索引和常规索引访问 2D 到 7D 矩阵的元素。我改变了我正在访问的元素以及我正在访问的矩阵大小,即每个维度的长度,但这并没有显着改变结果。我用于测试的文件在下面找到。使用的硬件是 Intel(R) Xeon(R) CPU E5-1620 v2 @ 3.70 GHz,16GB RAM。 MatLab 版本为 R2013B。
结果
Normal indexing 2D: 0.073659s
Linear indexing 2D: 0.064026s
Normal indexing 3D: 0.050719s
Linear indexing 3D: 0.064096s
Normal indexing 4D: 0.055674s
Linear indexing 4D: 0.062112s
Normal indexing 5D: 15.689907s
Linear indexing 5D: 5.265076s
Normal indexing 6D: 16.660496s
Linear indexing 6D: 5.295958s
Normal indexing 7D: 17.029072s
Linear indexing 7D: 5.291139s
在处理 4D 矩阵的性能方面,与线性索引相比,普通索引似乎非常相似。对于 3D 和 4D 矩阵,使用普通索引似乎稍微好一些。在 4D 矩阵之上,线性索引比正常索引更可取,但正常索引和常规索引都会受到巨大的性能损失(约两个数量级)。
结论
这个故事的寓意是在以高性能为目标时,在运行 MatLab 时仔细考虑矩阵中需要超过四个维度(除了显而易见的事实,例如 C++ 对于大多数应用程序来说要快得多等等,但这是另一个讨论可能)。
问题
如标题所示:当矩阵中超过四个维度时,性能大幅下降的(潜在)原因是什么?其他语言(例如 C++)是否也表现出这种行为?
用于测试的代码
clear all
clc
% Number if iterations
n=10000000;
A = rand(10,10);
k1=sub2ind(size(A),3,2);
fprintf('\n')
tic
for ii=1:n
A1=A(3,2);
end
a=toc;
fprintf('Normal indexing 2D: %fs\n',a)
tic
for ii=1:n
A2=A(k1);
end
a=toc;
fprintf('Linear indexing 2D: %fs\n',a)
B = rand(10,10,10);
k2=sub2ind(size(B),3,2,1);
tic
for ii=1:n
B1=B(3,2,1);
end
a=toc;
fprintf('Normal indexing 3D: %fs\n',a)
tic
for ii=1:n
B2=B(k2);
end
a=toc;
fprintf('Linear indexing 3D: %fs\n',a)
C = rand(10,10,10,10);
k3=sub2ind(size(C),3,2,1,10);
tic
for ii=1:n
C1=C(3,2,1,10);
end
a=toc;
fprintf('Normal indexing 4D: %fs\n',a)
tic
for ii=1:n
C2=C(k3);
end
a=toc;
fprintf('Linear indexing 4D: %fs\n',a)
D = rand(10,10,10,10,10);
k4=sub2ind(size(D),3,2,1,10,1);
tic
for ii=1:n
D1=D(3,2,1,10,1);
end
a=toc;
fprintf('Normal indexing 5D: %fs\n',a)
tic
for ii=1:n
D2=D(k4);
end
a=toc;
fprintf('Linear indexing 5D: %fs\n',a)
E = rand(10,10,10,10,10,10);
k5=sub2ind(size(E),3,2,1,10,1,2);
tic
for ii=1:n
E1=E(3,2,1,10,1,2);
end
a=toc;
fprintf('Normal indexing 6D: %fs\n',a)
tic
for ii=1:n
E2=E(k5);
end
a=toc;
fprintf('Linear indexing 6D: %fs\n',a)
F = rand(10,10,10,10,10,10,10);
k6=sub2ind(size(F),3,2,1,10,1,2,3);
tic
for ii=1:n
F1=F(3,2,1,10,1,2);
end
a=toc;
fprintf('Normal indexing 7D: %fs\n',a)
tic
for ii=1:n
F2=F(k6);
end
a=toc;
fprintf('Linear indexing 7D: %fs\n',a)
【问题讨论】:
-
只是一个小建议——您甚至不必将
toc保存到a! -
我知道,但我首先将 tocs 存储在另一个变量中用于绘图,确实有点冗余代码。
标签: c++ performance matlab multidimensional-array indexing