使用arrayfun在Matlab中更快地进行for循环?

时间:2011-06-21 10:08:46

标签: arrays matlab parallel-processing

目前我有以下部分代码:

for i = 2:N-1
  res(i) = k(i)/m(i)*x(i-1) -(c(i)+c(i+1))/m(i)*x(N+i) +e(i+1)/m(i)*x(i+1);
end

其中变量k,m,c和e是大小为N的向量,x是大小为2 * N的向量。使用像arrayfun这样的东西有没有办法更快地做到这一点!?我无法弄清楚这一点:(我特别想通过以后在GPU上运行来加快速度,因此,arrayfun也会有所帮助,因为matlab不支持并行化for循环而且我不想买夹克包... 非常感谢!

2 个答案:

答案 0 :(得分:6)

您不必使用arrayfun。如果使用使用一些智能索引,它可以工作:

    clear all

    N=20;
    k=rand(N,1);
    m=rand(N,1);
    c=rand(N,1);
    e=rand(N,1);
    x=rand(2*N,1);

    % for-based implementation
    %Watch out, you are not filling the first element of forres!
    forres=zeros(N-1,1); %Initialize array first to gain some speed.
    for i = 2:N-1
      forres(i) = k(i)/m(i)*x(i-1) -(c(i)+c(i+1))/m(i)*x(N+i) +e(i+1)/m(i)*x(i+1);
    end

    %vectorized implementation
    parres=k(2:N-1)./m(2:N-1).*x(1:N-2) -(c(2:N-1)+c(3:N))./m(2:N-1).*x(N+2:2*N-1) +e(3:N)./m(2:N-1).*x(3:N);

    %compare results; strip the first element from forres
    difference=forres(2:end)-parres %#ok<NOPTS>

答案 1 :(得分:5)

首先,MATLAB通过PARFOR支持并行循环。但是,由于计算量与您正在读写的数据量相比较小,因此加速此类计算的可能性不大。

要重构GPUArray“arrayfun”的内容,您需要使循环体中的所有数组引用引用循环迭代,并使循环遍及整个范围。您应该能够通过偏移某些数组并使用虚拟值填充来实现此目的。例如,您可以使用NaN添加所有数组,并将x(i-1)替换为新变量x_1 = [x(2:N) NaN]