CUDA:将一个向量的非零值位置复制到另一个

CUDA:将一个向量的非零值位置复制到另一个,cuda,gpgpu,Cuda,Gpgpu,在GPGPU上,使用cuda,我的问题是: 我有一个256个元素的向量,我想做一个程序,可以提取非零值的位置​​并将它们复制到另一个向量 我的代码不起作用: 开发历史:是数据源,初始向量 dev_Xn:是dev_Hist上非零值位置的向量 nN:是开发历史上非零值的数量 1。内核调用: gpu_Xn<<<1, nN>>>(dev_Hist, nN, dev_Xn) ; gpu\uxn(dev\uhist,nN,dev\uxn); 2。设备功能 __glob

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

我的代码不起作用:

开发历史:是数据源,初始向量

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

nN:是开发历史上非零值的数量

1。内核调用:

gpu_Xn<<<1, nN>>>(dev_Hist, nN, dev_Xn) ;
gpu\uxn(dev\uhist,nN,dev\uxn);
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] ;
}
\uuuuu全局\uuuuuu无效gpu Xn(int*pHist、int-pnN、int*pXn)
{
国际贸易署;
Tid=螺纹IDX.x;
__共享_uut tmpXn[256];
tmpXn[Tid]=0;
__同步线程();
__共享的_u; int idx;
如果(Tid==0)
idx=-1;
同步线程();
如果(pHist[Tid]!=0)
{
atomicAdd(&idx,1);
tmpXn[idx]=Tid;
}
__同步线程();
如果(Tid
这里的问题是您没有正确使用
atomicAdd
。虽然您正在以原子方式递增
idx
的值,但存储到共享内存的
idx
的读取不是原子的,这将产生未定义的行为

您的内核可能如下所示:

__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] ;
}
\uuuuu全局\uuuuuu无效gpu Xn(int*pHist、int-pnN、int*pXn)
{
国际贸易署;
Tid=螺纹IDX.x;
__共享_uu; int tmpXn[256];
__共享的_u; int idx;
tmpXn[Tid]=-1;
如果(Tid==0)idx=0;
__同步线程();
如果(pHist[Tid]!=0)
{
intx=atomicAdd(&idx,1);
tmpXn[x]=Tid;
}
__同步线程();
如果(Tid
[免责声明:在浏览器中编写,从未编译,使用风险自负]

请注意,
atomicAdd
返回正在进行原子更新的位置的上一个值。它是加载到共享内存时需要使用的值