gpt4 book ai didi

c++ - CUDA 小核 2d 卷积 - 怎么做

转载 作者:IT老高 更新时间:2023-10-28 23:01:22 30 4
gpt4 key购买 nike

我几天来一直在试验 CUDA 内核,以在 500x500 图像(但我也可以改变尺寸)和非常小的 2D 内核(拉普拉斯 2d 内核,因此它是 3x3 内核)之间执行快速 2D 卷积。 . 太小而无法利用所有 cuda 线程获得巨大优势)。

我创建了一个 CPU 经典实现(两个 for 循环,就像您想象的那样简单),然后我开始创建 CUDA 内核。

在几次令人失望的尝试执行更快的卷积之后,我最终得到了以下代码: http://www.evl.uic.edu/sjames/cs525/final.html (参见共享内存部分),它基本上让一个 16x16 线程 block 将他需要的所有卷积数据加载到共享内存中,然后执行卷积。

没什么,CPU 还是快了很多。我没有尝试 FFT 方法,因为 CUDA SDK 声明它对大内核大小很有效。

无论你是否阅读了我写的所有内容,我的问题是:

如何使用 CUDA 在相对较大的图像和非常小的内核 (3x3) 之间执行快速 2D 卷积?

最佳答案

你说得对,3x3 内核不适合基于 FFT 的方法。解决这个问题的最好方法是将内核推送到常量内存中(或者如果您使用的是 fermi+ 卡,这应该没什么大不了的)。

由于您知道内核大小,因此最快的方法是将输入图像/信号的 block 读取到共享内存中并执行展开的乘法和加法运算。

--

如果您愿意使用库来执行此操作ArrayFireOpenCV具有高度优化的卷积例程,可以为您节省大量开发时间。

我对 OpenCV 不太熟悉,但是在 ArrayFire 中您可以执行以下操作。

array kernel = array(3, 3, h_kernel, afHost); // Transfer the kernel to gpu
array image = array(w, h, h_image , afHost); // Transfer the image to gpu
array result = convolve2(image, kernel); // Performs 2D convolution

编辑

使用 ArrayFire 的额外好处是它的批处理操作允许您并行执行卷积。您可以通过 here 了解卷积如何支持批处理操作。

例如,如果您有 10 个图像要使用相同的内核进行卷积,您可以执行以下操作:

array kernel = array(3, 3, h_kernel, afHost);     // Transfer the kernel to gpu
array images = array(w, h, 10, h_images, afHost); // Transfer the images to gpu
array res = convolve2(images, kernel); // Perform all operations simultaneously

--

完全披露:我在 AccelerEyes 工作并积极致力于 ArrayFire。

关于c++ - CUDA 小核 2d 卷积 - 怎么做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10145452/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com