Arrays 仅使用一个块或线程太少时,Cuda共享内存超出范围
我自己尝试使用CUDA实现向量和归约,但遇到了一个可以修复但不理解实际问题的错误 我实现了下面的内核,它与NVIDIA示例中使用的内核非常相似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
__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);