Matlab 如何将涉及递归乘法和累加的循环向量化?
在Matlab 如何将涉及递归乘法和累加的循环向量化?,matlab,parallel-processing,vectorization,Matlab,Parallel Processing,Vectorization,在matlab中,我有一个如下形式的循环: a=1; for (i = 1:N) a = a * b(i) + c(i); end 此循环可以矢量化还是部分展开?对于长度分别为4的b和c,展开循环时,您将- output = b1b2b3b4 + c1b2b3b4 + c2b3b4 + c3b4 + c4 因此,一般公式是: output = b1b2b3...bN + c1b2b3..bN + c2b3..bN + c3b4..bN + ... cN-1bN + cN b的累加积可
matlab
中,我有一个如下形式的循环:
a=1;
for (i = 1:N)
a = a * b(i) + c(i);
end
此循环可以矢量化还是部分展开?对于长度分别为
4
的b
和c
,展开循环时,您将-
output = b1b2b3b4 + c1b2b3b4 + c2b3b4 + c3b4 + c4
因此,一般公式是:
output = b1b2b3...bN + c1b2b3..bN + c2b3..bN + c3b4..bN + ... cN-1bN + cN
b
的累加积可以通过元素翻转或“反转”来计算。Rest是所有元素与c
元素的相乘,元素移位1位,然后包括积算乘积和c
中剩余的标量元素,最后将所有元素相加,得到最终的标量输出
所以,编码的版本看起来像这样-
cumb = cumprod(b,'reverse');
a = sum(cumb(2:end).*c(1:end-1)) + cumb(1) + c(end);
标杆管理 让我们将问题中的循环方法与本文前面提出的向量化方法进行比较 以下是作为函数的方法-
function a = loopy(b,c)
N = numel(b);
a = 1;
for i = 1:N
a = a * b(i) + c(i);
end
return;
function a = vectorized(b,c)
cumb = cumprod(b,'reverse');
a = sum(cumb(2:end).*c(1:end-1)) + cumb(1) + c(end);
return;
下面是对这两种方法进行基准测试的代码-
datasizes = 10.^(1:8);
Nd = numel(datasizes);
time_loopy = zeros(1,Nd);
time_vectorized = zeros(1,Nd);
for k1 = 1:numel(datasizes)
N = datasizes(k1);
b = rand(1,N);
c = rand(1,N);
func1 = @() loopy(b,c);
func2 = @() vectorized(b,c);
time_loopy(k1) = timeit(func1);
time_vectorized(k1) = timeit(func2);
end
figure,
loglog(datasizes,time_loopy,'-rx'), hold on
loglog(datasizes,time_vectorized,'-b+'),
set(gca,'xgrid','on'),set(gca,'ygrid','on'),
xlabel('Datasize (# elements)'), ylabel('Runtime (s)')
legend({'Loop','Vectorized'}),title('Runtime Plot')
figure,
semilogx(datasizes,time_loopy./time_vectorized,'-k.')
set(gca,'xgrid','on'),set(gca,'ygrid','on'),
xlabel('Datasize (# elements)'), ylabel('Speedup (x)')
legend({'Speedup with vectorized method over loopy one'}),title('Speedup Plot')
这是运行时和加速图-
很少观察到
阶段#1:从开始数据大小到1000个元素,loopy方法占上风,因为矢量化方法没有获得足够的元素,无法从一次过的方法中受益
第二阶段:从1000个元素到10000000个元素,矢量化方法似乎是更好的方法,因为它可以获得足够的元素
阶段#3:对于较大的数据量情况,似乎使用矢量化方法存储和处理数百万个元素的内存带宽要求,而不是使用循环方法仅使用标量值
可能是追溯到矢量化方法
结论:如果性能是最重要的标准,那么可以使用矢量化方法,也可以根据数据大小使用原始的循环代码。。谢谢