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:对于较大的数据量情况,似乎使用矢量化方法存储和处理数百万个元素的内存带宽要求,而不是使用循环方法仅使用标量值 可能是追溯到矢量化方法


结论:如果性能是最重要的标准,那么可以使用矢量化方法,也可以根据数据大小使用原始的循环代码。

。谢谢