我有一个高矩阵(下面的示例是10000乘3000)我想要内部产品的行的子集(例如,500行)。对于不同的,随机选择的行重复多次(在该示例中为100次,但实际上多次)。事实证明索引A(sub,:)
相当慢。在我的例子中,最好乘以整个矩阵A
(即10000行),而不是选择性地选择和乘以实际需要的500。
行索引(sub = randperm(10000);
sub = sub(1:500);
)的随机生成在计算上是便宜的;为了公平,我把它放在两个循环中。
A=randn(10000,3000);
g=zeros(10000,1);
tic
for i=1:100
sub = randperm(10000); sub = sub(1:500);
b=randn(3000,1);
g(sub) = g(sub) + A(sub,:)*b;
end
toc
% elapsed time is 1.58 sec
tic
for i=1:100
sub = randperm(10000); sub = sub(1:500);
b=randn(3000,1);
g = g + A*b;
end
toc
% elapsed time is 1.28 sec
问题是:当实际只需要一部分行时,有没有办法加快速度?
答案 0 :(得分:1)
尝试跨行而不是列进行相乘。这可能需要您重新排列数据或应用标量转置(.'
)或两个,但由于这是阵列的本机形式,您可能会获得惊人的加速。例如,交换A
和g
的尺寸:
A = randn(3000,10000);
g = zeros(1,10000);
tic
for i = 1:100
sub = randperm(10000,500); % Taking @Dan's suggestion
b = randn(1,3000); % b is now a row vector
g(sub) = g(sub)+b*A(:,sub); % multiply across rows instead
end
toc
如果需要,您可以转置输出。在我的电脑上,这比第一种情况快了50%。
我认为至少其中一个根本原因是BLAS / LAPACK在这种情况下可以使用loop unrolling。