Cuda 使用AtomicAdd函数时,共享内存大小限制为最大线程数

Cuda 使用AtomicAdd函数时,共享内存大小限制为最大线程数,cuda,histogram,atomic,operation,Cuda,Histogram,Atomic,Operation,我使用原子运算来计算值的总和,比如直方图 因此,我首先使用共享内存将值存储在块中,然后将存储在每个块的共享内存中的值保存在全局内存中 整个代码如下 __global__ void KERNEL_RIGID_force_sum(part1*P1,part3*P3,int_t*nop_sol,Real*xcm,Real*ycm,Real*zcm,Real*sum_fx,Real*sum_fy,Real*sum_fz) { int_t i=threadIdx.x+blockIdx.x*bloc

我使用原子运算来计算值的总和,比如直方图

因此,我首先使用共享内存将值存储在块中,然后将存储在每个块的共享内存中的值保存在全局内存中

整个代码如下

__global__ void KERNEL_RIGID_force_sum(part1*P1,part3*P3,int_t*nop_sol,Real*xcm,Real*ycm,Real*zcm,Real*sum_fx,Real*sum_fy,Real*sum_fz)
{
    int_t i=threadIdx.x+blockIdx.x*blockDim.x;
    if(i>=k_num_part2) return;  
    if(P1[i].i_type==3) return;
    // if(P1[i].p_type<RIGID) return;

    // initilalize accumulation array in shared memory
    __shared__ int_t tmp_nop[128];
    __shared__ Real tmp_xcm[128],tmp_ycm[128],tmp_zcm[128];
    __shared__ Real tmp_fx[128],tmp_fy[128],tmp_fz[128];

    tmp_nop[threadIdx.x]=0;
    tmp_xcm[threadIdx.x]=0;
    tmp_ycm[threadIdx.x]=0;
    tmp_zcm[threadIdx.x]=0;
    tmp_fx[threadIdx.x]=0;
    tmp_fy[threadIdx.x]=0;
    tmp_fz[threadIdx.x]=0;
    __syncthreads();

    Real xi,yi,zi;
    Real fxi,fyi,fzi;
    int_t ptypei;
    
    ptypei=P1[i].p_type;
    xi=P1[i].x;    
    yi=P1[i].y;    
    zi=P1[i].z;
    fxi=P3[i].ftotalx;    
    fyi=P3[i].ftotaly;    
    fzi=P3[i].ftotalz;



    // save values to shared memory
    atomicAdd(&tmp_nop[ptypei],1);
    atomicAdd(&tmp_xcm[ptypei],xi);
    atomicAdd(&tmp_ycm[ptypei],yi);
    atomicAdd(&tmp_zcm[ptypei],zi);
    atomicAdd(&tmp_fx[ptypei],fxi);
    atomicAdd(&tmp_fy[ptypei],fyi);
    atomicAdd(&tmp_fz[ptypei],fzi);
    __syncthreads();

    // save shared memory values to global memory
    atomicAdd(&nop_sol[threadIdx.x],tmp_nop[threadIdx.x]);
    atomicAdd(&xcm[threadIdx.x],tmp_xcm[threadIdx.x]);
    atomicAdd(&ycm[threadIdx.x],tmp_ycm[threadIdx.x]);
    atomicAdd(&zcm[threadIdx.x],tmp_zcm[threadIdx.x]);
    atomicAdd(&sum_fx[threadIdx.x],tmp_fx[threadIdx.x]);
    atomicAdd(&sum_fy[threadIdx.x],tmp_fy[threadIdx.x]);
    atomicAdd(&sum_fz[threadIdx.x],tmp_fz[threadIdx.x]);

}
简单地说,当执行缩减的大小超过1024时,我不知道该怎么办

是否可以使用threadIdx.x以外的任何其他工具进行计算


你能给我一些建议吗?

共享内存的大小有限。大多数GPU的默认限制为48KB。它与threadblock中的线程数没有直接关系,但是您还没有指出您正在运行的GPU。得到的错误与每个块的线程数没有直接关系,而是与每个块请求的共享内存量有直接关系

如果您需要的共享内存量超过了可用的共享内存量,则需要提出另一种算法。例如,使用原子的共享内存缩减(您在这里看到的)可以转换为

另一种方法是确定是否可以减小正在使用的数组元素的大小。我不知道您的类型(
Real
int\u t
)对应于什么,但根据类型的不同,您可以通过转换为16位类型来获得更大的数组大小,例如,只要稍加努力,你甚至可以做到

ptxas error   : Entry function '_Z29KERNEL_RIGID_force_sum_sharedP17particles_array_1P17particles_array_3PiPdS4_S4_S4_S4_S4_' uses too much shared data (0xd000 bytes, 0xc000 max)