CUDA : Copy non-zero values position of a vector to another

标签 cuda gpgpu

在 GPGPU 上,使用 cuda 我的问题是: 我有一个 256 个元素的向量,我想制作一个程序,可以提取非零值的位置并将它们复制到另一个向量。

我的代码不起作用:

dev_Hist:是数据源,初始向量;

dev_Xn :是 dev_Hist 上非零值位置的向量;

nN :是 dev_Hist 上非零值的数量

<强>1。内核调用:

gpu_Xn<<<1, nN>>>(dev_Hist, nN, dev_Xn) ;

<强>2。设备功能

__global__ void gpu_Xn(int *pHist, int pnN, int* pXn) 
{
    int Tid ;
    Tid = threadIdx.x ;

    __shared__ T tmpXn[256] ;

    tmpXn[Tid] = 0 ;

    __syncthreads() ;

    __shared__ int idx ;

    if(Tid == 0)
        idx = -1  ;

    syncthreads() ;

    if(pHist[Tid] !=0)
    {
        atomicAdd(&idx, 1) ; 
        tmpXn[idx] = Tid ;
    }

    __syncthreads() ;
    if(Tid < pnN)
        pXn[Tid] = tmpXn[Tid] ;
}

最佳答案

这里的问题是您没有正确使用atomicAdd。尽管您以原子方式递增 idx 的值,但将 idx 存储到共享内存的读取不是原子的,这将产生 undefined行为。

你的内核可能应该是这样的:

__global__ void gpu_Xn(int *pHist, int pnN, int* pXn) 
{
    int Tid ;
    Tid = threadIdx.x ;

    __shared__ int tmpXn[256] ;
    __shared__ int idx ;

    tmpXn[Tid] = -1 ;
    if(Tid == 0) idx = 0  ;

    __syncthreads() ;

    if(pHist[Tid] !=0)
    {
        int x = atomicAdd(&idx, 1) ; 
        tmpXn[x] = Tid ;
    }

    __syncthreads() ;
    if(Tid < pnN)
        pXn[Tid] = tmpXn[Tid] ;
}

[免责声明:在浏览器中编写,从未编译,使用风险自担]

请注意,atomicAdd 返回被原子更新的位置的先前值。这是加载到共享内存时需要使用的值。

关于CUDA : Copy non-zero values position of a vector to another,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20939212/

相关文章:

gpgpu - 将 Tensorflow 与 GPU 一起使用时出错

opengl - Cuda 和 OpenGL 互操作的类型

python - 当使用大数组作为输入数据时出现 CUDA 错误

c++ - 在CUDA中取消分配数组的一部分

opengl - CUDA 立方体贴图纹理

memory - 如何找出GPU的共享内存和全局内存大小?

opencl - 如何计算 GPGPU 硬件中的峰值 FLOPS?

c++ - CUDA 'dot product' 内核能否加速批量 RMS 计算?

c++ - 编辑函数后出现 CL_INVALID_KERNEL_NAME 错误(更新日志文件)

python - 从 GPU 核心/线程的角度理解 Theano 示例