CUDA中图像行/列的线程索引

时间:2016-12-05 21:08:11

标签: c++ opencv cuda

所以我正在研究一个CUDA程序,在索引块和线程时我遇到了一些问题。基本上,我正在尝试在CUDA中实现Pixel Sort算法。 (通过一次修改,我们只处理 行或列,而不是同时处理两者)

我可视化的方式是简单地运行N个块,每个块有1个线程(对于行数或列数),并让每个块处理该行/列彼此独立。

因此,如果我们想对列进行排序,我们会像这样启动内核(有一些额外的参数只与我们的特定处理相关,所以为了简单起见,我将它们排除在外)

pixel_sort<<<cols, 1>>>(d_image, d_imageSort, rows, cols, ...);

然后在内核中,我用

访问块索引
int tid = blockIdx.x;

这允许我每块使用一行/列数据,但它有一些问题。对于较小的图像,它的运行速度比我们的算法的串行实现慢,而当图像尺寸变得太大时,它会直接崩溃。

我正在考虑的另一种线程方案是将每个图像的像素映射到一个线程,但是我对此有几个问题。

  1. 如果我们要使用M个线程启动N个块,表示具有M行的N个列,我们如何避免每个块的512(或1024?)个线程限制。在这个实例中,我们可以让每个线程处理列中的多个像素吗?索引在内核中的表现如何?
  2. 该算法基本上要求我们处理整个列,因此每个线程都不能在该像素上做一些工作,他们必须进行通信,大概是使用共享内存。在每个块中有一个“主”线程,进行实际的排序计算,然后让所有其他线程参与共享内存,这是一个有效的策略吗?
  3. 其他注释:

    • 我们的图像数据是通过OpenCV读取的,并且RGBA值存储在uchar4数组

1 个答案:

答案 0 :(得分:1)

如果每个块都有一个线程,则很快会遇到线程占用问题。如果您的目标是进行完整行排序(对于可以在发送到GPU以利用全局合并之前转置图像的列),获得合适结果的最快方法可能是对基数进行基数或合并排序基于每行,基本上从http://mgarland.org/files/papers/nvr-2008-001.pdf复制步骤。您可以为每行分配m个m个线程的块,使得km> =图像宽度。然后你将启动k *(图像高度)块。然后你的网格大小(k,高度,1)。

至于你的具体问题:

  1. 你无法绕过512/1024线程/块的限制,你必须重构你的算法。
  2. “主”线程通常是糟糕的设计,导致停顿,开销,并没有充分利用许多核心。您有时可能需要使用单个线程,比如输出/广播结果,但大多数情况下您想要避免它。请参阅链接文章,了解主要避免这种情况的示例算法。