具有该块输出的cuda滤波器是下一个块的输入

时间:2011-10-06 10:59:39

标签: gpu cuda

在下面的过滤器上工作时,我遇到了在GPU中处理图像这些代码片段的问题:

for(int h=0; h<height; h++) {
    for(int w=1; w<width; w++) {
    image[h][w] = (1-a)*image[h][w] + a*image[h][w-1];
    }
}

如果我定义:

  

dim3 threads_perblock(32,32)

然后我拥有的每个块:可以传送32个线程。该块的线程无法与其他块的线程通信。

在thread_block中,我可以使用shared_memory翻译那些代码片段,但是对于边缘(我想说):不同线程块中的图像[0,31]和图像[0,32]。图像[0,31]应该从图像[0,32]获得值以计算其值。但它们处于不同的线程块中。

这就是问题所在。

我该如何解决这个问题?

提前致谢。

2 个答案:

答案 0 :(得分:1)

如果image在全局内存中,则没有问题 - 您不需要使用共享内存,只需直接从image访问像素即可。

但是,如果您在此之前已经完成了一些处理,并且image的块已经在共享内存中,那么您就会遇到问题,因为您需要执行超出范围的邻居操作块。您可以执行以下操作之一 - 或者:

  • 将共享内存写回全局内存,以便相邻块可以访问(缺点:性能,块之间的同步可能很棘手)

或:

  • 以重叠(在这种情况下为1个像素)处理每个块的附加边缘像素,以便在每个块中有额外的像素来处理边缘情况,例如:使用34x34块大小但仅存储32x32中央输出像素(缺点:在内核中需要额外的逻辑,分支可能导致扭曲发散,并非块中的所有线程都被完全使用)

不幸的是,邻居操作在CUDA中可能非常棘手,并且总是存在一种无用的方法来处理边缘情况。

答案 1 :(得分:0)

你可以使用忙碌的旋转(不是玩笑)。只需让线程处理[32]执行:

while(!variable);

开始计算之前和线程处理[31]做

variable = 1;

完成时。由你来概括这一点。我知道这在CUDA中被认为是“流氓编程”,但它似乎是实现你想要的唯一方法。我有一个非常类似的问题,它对我有用。你的表现可能会受到影响...... 但要小心,

dim3 threads_perblock(32, 32) 

表示每个块有32 x 32 = 1024个线程。