CUDA 中的共享内存未获得分配给它的值,并且始终打印为零
Shared memory in CUDA is not getting values assigned to it and always prints zero
这个简单的归约函数可以在一个 CUDA 在线演示中找到。
__device__ void reducedSum(double* d_idata, double* d_odata, long LENGTH)
{
extern __shared__ double sdata[];
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < LENGTH) {
sdata[tid] = d_idata[i];
__syncthreads();
printf("Kernel sdata : %d \n", sdata[tid]);
for (unsigned int s = 1; s < blockDim.x; s *= 2)
{
if (tid % (2 * s) == 0)
{
sdata[tid] += sdata[tid + s];
}
__syncthreads();
}
if (tid == 0) {
d_odata[blockIdx.x] = sdata[0];
}
}
}
但是这里的printf总是打印如下输出。它预期做的实际上是从 d_idata 数组复制值并将其部分分配给每个共享内存块。然而它并没有发生。
调用内核如下:
long LENGTH = 10;
long N = 5;
int threadsPerBlock = N;
int numBlocks = (threadsPerBlock + LENGTH - 1) / threadsPerBlock;
cudaCalc<<<numBlocks, threadsPerBlock, N*sizeof(double)>>> (d_vec1, d_vec2, d_dotProduct, ....)
现在在内核中我调用这个 reducedSum __device__ 函数如下。
__global__ void cudaCalc(int* d_vec1, int* d_vec2, double* d_dotProduct, ... )
{
int tid_0 = threadIdx.x;
int index = blockDim.x * blockIdx.x + threadIdx.x;
if (index < LENGTH) {
d_dotProduct[index] = (double) d_vec1[index] * d_vec2[index];
d_squared1[index] = (double)d_vec1[index] * d_vec1[index];
d_squared2[index] = (double)d_vec2[index] * d_vec2[index];
__syncthreads();
}
reducedSum(d_squared1, d_squaredSum1, LENGTH);
reducedSum(d_squared2, d_squaredSum2, LENGTH);
reducedSum(d_dotProduct, d_dotSum, LENGTH);
}
能不能有一些好的sir/madam请告诉我哪里错了?我已经在这几个小时了。如果您想查看其余代码,请请求。提前谢谢你。
错误出在 printf 函数上。我不敢相信我花了几个小时在这上面。
printf("Kernel sdata : %d \n", sdata[tid]);
占位符是整数,而sdata是双精度数组。问题解决了。
nvcc 编译器没有针对此类错误显示警告或错误,真是太可惜了。另一方面,gcc 显示了很多警告。这应该是一个建议。
这个简单的归约函数可以在一个 CUDA 在线演示中找到。
__device__ void reducedSum(double* d_idata, double* d_odata, long LENGTH)
{
extern __shared__ double sdata[];
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < LENGTH) {
sdata[tid] = d_idata[i];
__syncthreads();
printf("Kernel sdata : %d \n", sdata[tid]);
for (unsigned int s = 1; s < blockDim.x; s *= 2)
{
if (tid % (2 * s) == 0)
{
sdata[tid] += sdata[tid + s];
}
__syncthreads();
}
if (tid == 0) {
d_odata[blockIdx.x] = sdata[0];
}
}
}
但是这里的printf总是打印如下输出。它预期做的实际上是从 d_idata 数组复制值并将其部分分配给每个共享内存块。然而它并没有发生。
调用内核如下:
long LENGTH = 10;
long N = 5;
int threadsPerBlock = N;
int numBlocks = (threadsPerBlock + LENGTH - 1) / threadsPerBlock;
cudaCalc<<<numBlocks, threadsPerBlock, N*sizeof(double)>>> (d_vec1, d_vec2, d_dotProduct, ....)
现在在内核中我调用这个 reducedSum __device__ 函数如下。
__global__ void cudaCalc(int* d_vec1, int* d_vec2, double* d_dotProduct, ... )
{
int tid_0 = threadIdx.x;
int index = blockDim.x * blockIdx.x + threadIdx.x;
if (index < LENGTH) {
d_dotProduct[index] = (double) d_vec1[index] * d_vec2[index];
d_squared1[index] = (double)d_vec1[index] * d_vec1[index];
d_squared2[index] = (double)d_vec2[index] * d_vec2[index];
__syncthreads();
}
reducedSum(d_squared1, d_squaredSum1, LENGTH);
reducedSum(d_squared2, d_squaredSum2, LENGTH);
reducedSum(d_dotProduct, d_dotSum, LENGTH);
}
能不能有一些好的sir/madam请告诉我哪里错了?我已经在这几个小时了。如果您想查看其余代码,请请求。提前谢谢你。
错误出在 printf 函数上。我不敢相信我花了几个小时在这上面。
printf("Kernel sdata : %d \n", sdata[tid]);
占位符是整数,而sdata是双精度数组。问题解决了。
nvcc 编译器没有针对此类错误显示警告或错误,真是太可惜了。另一方面,gcc 显示了很多警告。这应该是一个建议。