Cuda 过滤图像、最佳做法

Cuda 过滤图像、最佳做法,cuda,opencl,gpgpu,Cuda,Opencl,Gpgpu,我有一个输入图像“让它成为1024*1024像素的缓冲区,带有RGBA颜色数据” 我想对每个像素做的是根据相邻像素进行过滤,比如x和y方向的[-15,15] 因此,我担心的是,使用全局内存执行此操作将类似于对每个像素进行31*31全局内存访问“这将是非常大的性能瓶颈”,而且我不确定多个线程同时尝试从同一内存位置读取数据的行为“可能是其中一些线程无法读取so->垃圾数据输入->垃圾数据输出” 这个问题是针对CUDA或OpenCL的,因为概念应该是相同的 我知道共享内存(每个工作组)或本地内存(每个

我有一个输入图像“让它成为1024*1024像素的缓冲区,带有RGBA颜色数据”

我想对每个像素做的是根据相邻像素进行过滤,比如x和y方向的[-15,15]

因此,我担心的是,使用全局内存执行此操作将类似于对每个像素进行31*31全局内存访问“这将是非常大的性能瓶颈”,而且我不确定多个线程同时尝试从同一内存位置读取数据的行为“可能是其中一些线程无法读取so->垃圾数据输入->垃圾数据输出”

这个问题是针对CUDA或OpenCL的,因为概念应该是相同的
我知道共享内存(每个工作组)或本地内存(每个线程)无法解决此问题,因为我无法读取另一个线程本地内存,或另一个组共享内存“如果我误解了此概念,请纠正我”

共享内存是解决此问题的典型方法,尽管模具区域(31*31)相当大。然而,仍然可以获得数据重用的好处。由于相邻像素计算仅扩展一列所需的区域,因此在32位RGBA像素的16KB共享内存阵列中,您可以拥有足够的数据,至少64个线程可以在单个共享内存负载中协同计算其像素值

关于多个线程读取同一位置的问题,不可能进行垃圾数据读取。当然存在争用导致性能影响的可能性,但事实上,在内核中有一个有序的for循环进程,无论如何,没有线程会在同一时间读取相同的位置。通过适当的数据组织,将有很好的机会从全局内存进行联合读取,并且在共享内存中不会发生库冲突


这类问题非常适合GPU,例如CUDA或OpenCL,类似的程序也有很多。

让组线程按[0~31][0~31]的方式排列。。。第一组中的线程20如何访问第二组中的线程20的共享内存?由于窗口围绕着每个线程,“因此我必须访问前15个线程和后15个线程”,共享内存与单个线程或线程组没有关联。它与threadblock关联,即threadblock中的所有线程。threadblock中的任何线程都可以访问与该threadblock关联的共享内存。我知道这一点!!,块内的所有32*32线程都可以访问此块中的共享内存,但这里的问题是,例如:全局内存ID pixel(420390)希望访问范围(420-15390-15)到(420+15390+15)的像素,因此如果我们将全局内存存储到共享内存中,则只有块中的中心线程将准备好其数据,所有其他线程都需要访问邻居块共享内存“这是不可能的”是的,所以您不需要将32*32数据元素加载到共享内存中。为每个附加线程加载32*32个数据元素加上一个附加列(32个元素)。该附加线程所需的其余数据与您为上一个线程加载的数据相同。我并不是建议使用32*32线程块。我建议总共有64个线程。对于64个线程,共享内存中大约需要32*32像素加上32*63像素。这当然是可行的,并且将为所有64个线程提供足够的数据来计算64个相邻像素点的a的值。它恰好是三维的,而不是二维的,但是概念是相同的。