CUDA和并行寻址位

时间:2016-03-23 14:38:40

标签: cuda gpgpu gpu-programming

我想编写一个CUDA程序,它返回一个包含特定条件的更大数组的位置。

执行此操作的简单方法是编写一个内核,如果保留条件,则返回一个整数数组,如果不符合,则返回0。

另一种方法可能只返回找到的索引 - 但根据我对GPU同步的了解(这相当于在GPU上实现队列/链接列表)会产生问题。

提出的第一个想法的问题是数组将处于输入大小。

我想到的另一种方法是创建一个大小为log(n)/ 8 + 1的数组(n =我检查的项目数),并为每个数组位置使用1位(保持一种压缩表示形式)输出)。

我唯一找不到的是CUDA是否支持并行位寻址..

我现在如何做的一个例子:

__global__ void test_kernel(char *gpu, char *gpuFind, int *gputSize, int *gputSearchSize, int *resultsGPU)
{
   int start_idx = threadIdx.x + (blockIdx.x * blockDim.x);

   if (start_idx > *gputTextSize - *gputSearchSize){return;}

   unsigned int wrong=0;
   for(int i=0; i<*gputSearchSize;i++){
     wrong = calculationOnGpu(gpuText, gpuFind, start_idx,i, gputSearchSize);
   }

   resultsGPU[start_idx] = !wrong;

} 

我想要做的不是使用int或char作为“resultsGpu”变量,而是使用别的东西。

由于

1 个答案:

答案 0 :(得分:4)

在1,2,4,8或16 字节的边界上的CUDA GPU can access items。它无法独立访问字节中的位。

通过读取更大的项目(例如charint),修改寄存器中的位,然后将该项目写回存储器,可以修改字节中的位。因此,它将是一个读 - 修改 - 写操作。

为了在具有多个线程的场景中保留相邻位,有必要以原子方式更新项(charint等等。)没有原子操作{ {1}}数量,因此需要将这些位分组为32的数量,并写入例如为char。遵循这个习惯用法,每个线程都会进行原子操作。

32当前也恰好是扭曲尺寸,因此基于扭曲的内在可能是更有效的方式,特别是warp vote int函数。像这样:

__ballot()

您还没有提供完整的代码,因此上面只是一个如何完成的草图。我不确定原始内核中的循环无论如何都是一种有效的方法,并且上面假设每个数据项要搜索1个线程。即使在搜索到的数组的一端或另一端存在非活动线程时,__global__ void test_kernel(char *gpu, char *gpuFind, int *gputSize, int *gputSearchSize, int *resultsGPU) { int start_idx = threadIdx.x + (blockIdx.x * blockDim.x); if (start_idx > *gputTextSize - *gputSearchSize){return;} unsigned int wrong=0; wrong = calculationOnGpu(gpuText, gpuFind, start_idx,0, gputSearchSize); wrong = __ballot(wrong); if ((threadIdx.x & 31) == 0) resultsGPU[start_idx/32] = wrong; } 也应该是安全的。