使用CUDA卷积多个小矩阵的最佳方法

时间:2013-07-30 19:10:22

标签: cuda gpgpu convolution

我需要用小矩阵和内核预先形成多个卷积,我希望利用GPU的许多处理器能够让我尽可能快地完成它。

问题如下:我有很多矩阵(~1,000到~10,000)或相对较小的尺寸(~15x15下至1x1 - 与标量一样),以及一定数量的卷积掩模(~20到1)。我需要用每个卷积模板对所有矩阵进行卷积 例如:

A; %5,000 matrices of size 10x10, A(i) = a 10x10 matrix
B; 10 matrices of size 5x5, B(k) = a 5x5 matrix
res(j)=conv(A,B(1)); %res(j) is the result of convolving all 5,000
%matrices in A by the j'th kernel B(j)

目标是尽可能快地计算res(1),...,res(10)

我想听听有关如何实施最有效算法的建议。 基于FFT的卷积可能太慢了。

到目前为止,我看到的每个实现都是2d卷积,意味着卷积2个大矩阵,而我需要卷积许多小矩阵。

我现在对CUDA编程知之甚少,但我正在学习。

我希望自己能够解决这个问题,但由于时间限制,我不得不向任何有经验的人提出任何建议,而我会学习如何在CUDA中编码。

谢谢!

P.S。任何适合我目的的实现指针都非常感激。我是大学生,这是一个小型的研究项目,所以我不需要为此付出代价......

2 个答案:

答案 0 :(得分:2)

我不会假装给你一个问题的最终答案,但我想指出一些事情:

  1. 正如您所提到的,第一种可能性是使用FFT方法。这一行的一个问题是(如果我错了,请纠正我)cuFFT库主要用于处理大型矩阵,因此从这种方法中获益的有效方法是开发对小型矩阵有效的FFT程序。我只是想表明有一些这类算法,请参阅例如论文:Small Discrete Fourier Transforms on GPUs。我对CUDA FFT在指定类型的小矩阵上的性能没有直接的经验,但也许它可能对您有意义,因为掩码矩阵的数字较小(10),因此您可以“回收”他们的FFT用于大量卷积(5000)。
  2. 如果您决定不使用FFT方法,那么,如果您拥有具有计算能力>=3.5的GPU架构,那么动态并行可能是计算卷积的良好候选者。如果您将每个卷积矩阵元素的评估视为插值,那么您将遇到大小为15x15的插值问题,并且动态并行性可能有所帮助,请参阅帖子:Benefit of splitting a big CUDA kernel and using dynamic parallelism

答案 1 :(得分:0)

一种方法是使用我工作的ArrayFire的GFOR loop

您可以根据需要将尽可能多的小convolutions平铺到一个大内核启动中,只要您没有耗尽GPU内存,如下所示:

array x = randu(5);      // the input
array y = randu(m,5);    // the output
array f = constant(1,3); // the kernel
gfor (array k, 0, m-1) {
    y(span,k) = convolve(x,f);
}
祝你好运!