CUDA和并行寻址位

CUDA和并行寻址位,cuda,gpgpu,gpu,Cuda,Gpgpu,Gpu,我想写一个CUDA程序,返回包含特定条件的较大数组的位置 最简单的方法是编写一个内核,如果保留条件,则返回一个整数数组,如果不保留条件,则返回0 另一种方法可能是只返回找到的索引,但根据我对GPU同步的了解,这可能会有问题(相当于在GPU上实现队列/链表) 提出的第一个想法的问题是,数组将处于输入大小 我考虑的另一种方法是创建一个大小为log(n)/8+1(n=我检查的项目数)的数组,并为每个数组位置使用1位(保存输出的某种压缩表示) 我唯一找不到的是CUDA是否支持并行位寻址 我现在如何做的一

我想写一个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;

} 
\uuuu全局\uuuu无效测试\u内核(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;}
无符号整数错误=0;
对于(int i=0;i1、2、4、8或16字节边界上的CUDA GPU,它不能独立访问字节中的位

字节中的位可以通过读取较大的项来修改,例如
char
int
,修改寄存器中的位,然后将该项写回内存。因此,这将是一个读-修改-写操作

为了在这种具有多个线程的场景中保留相邻位,有必要自动更新该项(
char
int
,等等)没有对
char
数量进行操作的原子,因此需要将位分组为32个数量,并写入例如
int
。按照该习惯用法,每个线程都将执行原子操作

32也恰好是当前的扭曲大小,因此基于扭曲的内在函数可能是更有效的方法,尤其是
\u ballot()
函数。类似如下:

__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;

} 
您还没有提供完整的代码,因此上面只是一个如何完成的示意图。我不确定原始内核中的循环是否是一种有效的方法,上面假设每个要搜索的数据项有一个线程。
\u ballot()
即使在被搜索阵列的一端或另一端存在非活动线程,也应该是安全的