【问题标题】:Speed up convolution computation code加速卷积计算代码
【发布时间】:2015-04-26 16:44:38
【问题描述】:

我在 MATLAB 中有以下代码

[Mx,Nx] = size(x);
[My,Ny] = size(y);

padded_x = zeros(Mx+2*(My-1),Nx+2*(Ny-1));
padded_x(My:Mx+My-1,Ny:Ny+Nx-1) = x; 
y = rot90(y,2);

z = zeros(Mx+My-1,Nx+Ny-1);
for i=1:Mx+My-1
    for j=1:Nx+Ny-1
        z(i,j) = sum(sum(padded_x(i:i+My-1,j:j+Ny-1).*y));
    end
end

这是 2D 卷积实现的一部分。有什么办法可以让这变得更快吗?例如向量化这 2 个 for 循环? 我知道有更快的算法可以计算 2D 卷积,但我想加快这一速度。因此,我不是在寻找具有不同复杂度的算法,而只是在寻找具有较低复杂度常数的算法。我也想把它保存在 MATLAB 中,而不是使用 MEX - 文件等。最后,提供的 conv2 函数也不是我正在寻找的解决方案。

【问题讨论】:

  • 并且您不想使用提供的conv2 函数?
  • 不,抱歉我忘了提!其实conv2使用的是FFT,所以我认为很明显它属于“不同算法”类别
  • @Controller 我不知道conv2 使用了fft。找到这方面的信息也不是很容易。但是,有没有关系?
  • @patrik 好吧,是的,在这种情况下确实如此,因为它会导致不同的复杂性。这个概念是看这两种算法(mine 和 conv2)如何随着输入的大小而扩展。我只是想知道是否可以更快地实现我的算法,以便更好地近似两种算法之间的差异。
  • xy 的典型数据大小是多少?

标签: performance matlab convolution


【解决方案1】:

对于每次迭代,您可以用fast matrix multiplication 替换逐元素乘法和双重求和。

那是-

z(i,j) = sum(sum(padded_x(i:i+My-1,j:j+Ny-1).*y));

将被替换为 -

M = padded_x(i:i+My-1,j:j+Ny-1);
z(i,j) = M(:).'*y(:);

因此,原始代码的循环部分可以替换为 -

z = zeros(Mx+My-1,Nx+Ny-1);
yr = y(:);
for i=1:Mx+My-1
    for j=1:Nx+Ny-1
         M = padded_x(i:i+My-1,j:j+Ny-1);
        z(i,j) = M(:).'*yr;
    end
end

快速测试:xy 分别为 200 x 200,运行时是 -

------------------------- With Original Approach
Elapsed time is 10.357977 seconds.
------------------------- With Proposed Approach
Elapsed time is 5.209822 seconds.

【讨论】:

  • 可以做 z(i,j) =yr * M(:);如果您执行 yr=y(:),则在内部循环中。前期可以多挤一点
  • @hiandbaii 啊,好观察! OP 也必须考虑这种 hack!
猜你喜欢
  • 2011-08-27
  • 2013-01-13
  • 1970-01-01
  • 1970-01-01
  • 2013-09-06
  • 2018-06-25
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多