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