【问题标题】:Theoretical speedup not achieved - kernel separability未实现理论加速 - 内核可分离性
【发布时间】:2014-11-20 04:19:17
【问题描述】:

我正在了解如何使用内核可分离性来改进卷积所需的时间。下面是一段代码展示了这一点:

test = randn(3000);
kx = [1 2 3 4 5 6 7 8 9];
ky = kx';
kernel = ky*kx;

tic; b = conv2(test,kernel,'same'); toc;

tic; bx=conv2(test,kx, 'same'); by=conv2(bx,ky, 'same'); toc;

运行上述代码会产生以下结果:

经过的时间是 0.564579 秒。 经过的时间是 0.333260 秒。

可以看出,这不是我期望的理论加速比,应该是 81/18 = 4.5。

谁能解释一下原因?

【问题讨论】:

  • 可能是各种各样的东西。这也可能是由于您两次调用该函数的函数开销。请记住,这些是理论上的加速。实际上是另一个故事。此外,该代码是在函数中还是在命令提示符中运行?如果您在命令提示符下运行它,则会有额外的时间开销。
  • 还要注意,对于如此少量的处理,这些时间非常长,因此这些时间可能被卷积本身以外的操作所淹没。尝试将内核应用于大小合适的 2D 数据集,例如1024x1024。
  • 比较一下,当我运行这两行代码时,我分别得到了0.0729470.067429 秒。我可能进行了 10 次不同的测试,而我的时间则徘徊在这些时间之间。我把它放到一个函数脚本中并运行它......所以我没有看到任何明显的区别。也许conv2 在提供 2D 内核时会考虑可分离性,并在可能的情况下将其拆分为 2 个 1D 内核。
  • 也试试tic; by=conv2(kx, ky, test, 'same'); toc
  • @user1816546 - 将您的代码放在函数脚本中并运行它。直接在命令提示符下执行此操作会产生额外的开销。

标签: performance matlab convolution


【解决方案1】:

您的内核不够大,无法真正看到任何收益。随着内核变大,改进应该会变得更加明显:

test = randn(3000);
kx = 1:100;
ky = kx';
kernel = ky*kx;

tic; b = conv2(test,kernel,'same'); toc;
tic; bx=conv2(test,kx, 'same'); by=conv2(bx,ky, 'same'); toc;

当我使用这个 100x100 内核大小运行它时,我看到:

Elapsed time is 6.961222 seconds.
Elapsed time is 0.252186 seconds.

使用 200x200 内核,我得到:

Elapsed time is 28.894932 seconds.
Elapsed time is 0.639125 seconds.

当我们将内核大小加倍时,二维内核时间增加了约 4.15 倍,而一维时间增加了约 2.5 倍。分别离理论增长4倍和2倍不远。

【讨论】:

    【解决方案2】:

    这不是在回答您的问题(kmac 的回答涵盖了该问题),但如果您正在寻找性能改进,那么最好不要使用 conv 函数。在 Matlab 中执行 FFT/IFFT 以达到相同的结果要快得多。从传统卷积到傅立叶方法有几个权衡,但它可能对您的应用有所帮助。这里有一些关于这个主题的很棒的想法:
    http://blogs.mathworks.com/steve/2009/11/03/the-conv-function-and-implementation-tradeoffs/

    【讨论】:

      猜你喜欢
      • 2011-06-09
      • 1970-01-01
      • 2012-08-07
      • 2017-12-10
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 2014-03-02
      • 2014-11-06
      相关资源
      最近更新 更多