Image processing 多维内核执行的CUDA动机

Image processing 多维内核执行的CUDA动机,image-processing,cuda,gpgpu,Image Processing,Cuda,Gpgpu,CUDA将工作划分为块是合乎逻辑的,因为它反映了硬件(单个执行单元中的一些执行线程,都在同一个“块”中) 然而,在我研究图像处理算法的实现时,还不完全清楚为什么我应该有块的二维网格,每个块都是线程的二维网格。为什么1D不行?毕竟,内核调用通常只将图像视为像素的线性一维数组,并且必须通过乘以通常的行*列+列中的偏移量来计算其全局索引 我的一个猜测是空间位置。我们通常根据像素周围的像素计算像素的内容,因此2D线程网格确保所有相邻像素在同一执行单元内运行,从而可以共享本地内存等。这是否正确?我还缺什么

CUDA将工作划分为块是合乎逻辑的,因为它反映了硬件(单个执行单元中的一些执行线程,都在同一个“块”中)

然而,在我研究图像处理算法的实现时,还不完全清楚为什么我应该有块的二维网格,每个块都是线程的二维网格。为什么1D不行?毕竟,内核调用通常只将图像视为像素的线性一维数组,并且必须通过乘以通常的行*列+列中的偏移量来计算其全局索引

我的一个猜测是空间位置。我们通常根据像素周围的像素计算像素的内容,因此2D线程网格确保所有相邻像素在同一执行单元内运行,从而可以共享本地内存等。这是否正确?我还缺什么?也许编程很容易(尽管这很难相信,因为代码计算的是1D偏移量)


提前感谢AFAIK使用2D/3D网格的唯一原因是它是否与数据相关。如果有二维数据(图像…)或三维数据(粒子系统等),可以通过使用适当的块尺寸使代码更可读。此外,在旧卡上,一个维度中的块数限制为65535,因此使用其他维度来绕过它


无论使用1D线程块还是2D/3D线程块,性能都应该没有差别。

AFAIK使用2D/3D网格的唯一原因是它是否与数据相关。如果有二维数据(图像…)或三维数据(粒子系统等),可以通过使用适当的块尺寸使代码更可读。此外,在旧卡上,一个维度中的块数限制为65535,因此使用其他维度来绕过它


无论您使用1D线程块还是2D/3D线程块,性能应该没有差别。

但代码的可读性不高,因为无论如何,传递到内核的数据几乎总是1D数组,您需要重新计算与坐标的偏移量。@zlatanski:这确实取决于数据,我不会说它“几乎总是1D数组”:)我的意思是,您找到的所有图像处理样本都有作为
uchar4*
传入的数据,然后您从线程的全局索引计算您在该数组中的位置。线程全局索引是二维的这一事实很难使代码更易于阅读,但是如果您查看所有图像处理教程和文档,它们确实使用二维执行模式。因此,回到我最初的问题,任何必要的索引都可以合成。将一组线程称为“线”与“方”是任意的。与1D线程网格相比,2D线程网格并没有什么神奇之处,因为它可以确定邻居是谁。是的,我确实认为从概念上来说,生成索引可能更容易,并且可以生成更可读的代码(这可能就是为什么您可以找到大量示例的原因),但是您很快就将这些内容删除了。无论如何,这种类型的讨论在我看来主要是基于观点的。我想不出一个用1D无法实现的2D示例。但代码的可读性不高,因为无论如何,传递到内核中的数据几乎都是1D数组,您需要重新计算与坐标的偏移量。@zlatanski:这确实取决于数据,我不会说它“几乎总是1D数组”:)我的意思是,您找到的所有图像处理样本都有作为
uchar4*
传入的数据,然后您从线程的全局索引计算您在该数组中的位置。线程全局索引是二维的这一事实很难使代码更易于阅读,但是如果您查看所有图像处理教程和文档,它们确实使用二维执行模式。因此,回到我最初的问题,任何必要的索引都可以合成。将一组线程称为“线”与“方”是任意的。与1D线程网格相比,2D线程网格并没有什么神奇之处,因为它可以确定邻居是谁。是的,我确实认为从概念上来说,生成索引可能更容易,并且可以生成更可读的代码(这可能就是为什么您可以找到大量示例的原因),但是您很快就将这些内容删除了。无论如何,这种类型的讨论在我看来主要是基于观点的。我想不出一个用1D无法实现的2D的好例子。