Arrays 仅使用一个块或线程太少时,Cuda共享内存超出范围

Arrays 仅使用一个块或线程太少时,Cuda共享内存超出范围,arrays,cuda,gpu,shared-memory,nvidia,Arrays,Cuda,Gpu,Shared Memory,Nvidia,我自己尝试使用CUDA实现向量和归约,但遇到了一个可以修复但不理解实际问题的错误 我实现了下面的内核,它与NVIDIA示例中使用的内核非常相似 __global__ void reduce0(int *input, int *output) { extern __shared__ int s_data[]; int tid = threadIdx.x; int i = blockIdx.x * blockDim.x + threadIdx.x; s_data

我自己尝试使用CUDA实现向量和归约,但遇到了一个可以修复但不理解实际问题的错误

我实现了下面的内核,它与NVIDIA示例中使用的内核非常相似

__global__ 
void reduce0(int *input, int *output)
{
    extern __shared__ int s_data[];

    int tid = threadIdx.x;
    int i = blockIdx.x * blockDim.x + threadIdx.x;

    s_data[tid] = input[i];
    __syncthreads();

    for( int s=1; s < blockDim.x; s *= 2) {
        if((tid % 2*s) == 0) {
            s_data[tid] += s_data[tid + s];
        }

        __syncthreads();
    }

    if(tid == 0) {
        output[blockIdx.x] = s_data[0];
    }
}
如果使用了超过1个线程块,那么代码运行正常。仅使用1个块将导致上述索引越界错误。通过将我的主机代码与以下示例之一进行比较来查找我的错误:

int smemSize = (threads <= 32) ? 2 * threads * sizeof(T) : threads * sizeof(T);
int-smemize=(线程代码崩溃
  • >2个块,任意数量的线程=>代码运行fine
  • 1个块,任意数量的线程,共享内存大小2*#线程=>代码运行fine
  • 虽然考虑了几个小时,我不明白为什么在使用太少的线程或块时会出现越界错误

    更新:主机代码根据请求调用内核

    int numberOfValues = 1024 ;
    int numberOfThreadsPerBlock = 32;
    int numberOfBlocks = numberOfValues / numberOfThreadsPerBlock;
    
    int memSize = sizeof(int) * numberOfValues;
    
    int *values = (int *) malloc(memSize);
    int *result = (int *) malloc(memSize);
    
    int *values_device, *result_device;
    cudaMalloc((void **) &values_device, memSize);
    cudaMalloc((void **) &result_device, memSize);
    
    for(int i=0; i < numberOfValues ; i++) {
        values[i] = i+1;
    }
    
    cudaMemcpy(values_device, values, memSize, cudaMemcpyHostToDevice);
    
    dim3 dimGrid(numberOfBlocks,1);
    dim3 dimBlock(numberOfThreadsPerBlock,1);
    int sharedMemSize = numberOfThreadsPerBlock * sizeof(int);
    
    reduce0 <<< dimGrid, dimBlock, sharedMemSize >>>(values_device, result_device);
    
    if (cudaSuccess != cudaGetLastError())
            printf( "Error!\n" );
    
    cudaMemcpy(result, result_device, memSize, cudaMemcpyDeviceToHost);
    
    int numberOfValues=1024;
    int numberOfThreadsPerBlock=32;
    int numberOfBlocks=numberOfValues/numberOfThreadsPerBlock;
    int memSize=sizeof(int)*numberOfValues;
    int*值=(int*)malloc(memSize);
    int*result=(int*)malloc(memSize);
    int*值\u设备,*结果\u设备;
    cudamaloc((void**)和设备的值,memSize);
    cudamaloc((void**)和result_设备,memSize);
    对于(int i=0;i(值\u设备、结果\u设备);
    if(cudaSuccess!=cudaGetLastError())
    printf(“错误!\n”);
    cudaMemcpy(结果、结果_设备、memSize、cudaMemcpyDeviceToHost);
    
    您的问题可能是模和乘法的优先顺序。
    tid%2*s
    等于
    (tid%s)*2
    但您需要
    tid%(s*2)


    为什么需要使用
    int-smemize=(线程可以显示内核调用吗?请检查启动参数-很容易混淆它们的顺序。我在问题中添加了主机代码
    
    int numberOfValues = 1024 ;
    int numberOfThreadsPerBlock = 32;
    int numberOfBlocks = numberOfValues / numberOfThreadsPerBlock;
    
    int memSize = sizeof(int) * numberOfValues;
    
    int *values = (int *) malloc(memSize);
    int *result = (int *) malloc(memSize);
    
    int *values_device, *result_device;
    cudaMalloc((void **) &values_device, memSize);
    cudaMalloc((void **) &result_device, memSize);
    
    for(int i=0; i < numberOfValues ; i++) {
        values[i] = i+1;
    }
    
    cudaMemcpy(values_device, values, memSize, cudaMemcpyHostToDevice);
    
    dim3 dimGrid(numberOfBlocks,1);
    dim3 dimBlock(numberOfThreadsPerBlock,1);
    int sharedMemSize = numberOfThreadsPerBlock * sizeof(int);
    
    reduce0 <<< dimGrid, dimBlock, sharedMemSize >>>(values_device, result_device);
    
    if (cudaSuccess != cudaGetLastError())
            printf( "Error!\n" );
    
    cudaMemcpy(result, result_device, memSize, cudaMemcpyDeviceToHost);