我看到如何使用内核可分性来改善卷积所需的时间。下面是一段代码,展示了这一点:
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。
任何人都可以解释原因吗?
答案 0 :(得分: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.
当我们将内核大小加倍时,2D内核时间增加了~4.15倍,1D时间增加了~2.5倍。与理论增长分别为4倍和2倍不远。
答案 1 :(得分:1)
这不是回答你的问题(kmac的回答涵盖了这个问题),但是如果你正在寻找性能改进,那么你可能最好远离conv
功能。在Matlab中进行FFT / IFFT以获得相同的结果要快得多。从传统的卷积到傅立叶方法有几种权衡,但它可能对您的应用有所帮助。关于这个话题有一些很好的想法:
http://blogs.mathworks.com/steve/2009/11/03/the-conv-function-and-implementation-tradeoffs/