[英]Why is this simple CUDA kernel getting a wrong result?
我是 CUDA 的新手。 我正在学习一些基本的东西,因为我想在其他项目中使用 CUDA。 我编写了这段代码,以便从已填充 1 的 8x8 方阵中添加所有元素,因此结果必须为 64。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
const int SIZE = 64;
__global__ void add_matrix_values(int* matrix, int sum, int c)
{
int i = threadIdx.x + blockIdx.x * blockDim.x;
int j = threadIdx.y + blockIdx.x * blockDim.x;
sum += matrix[i*c+j];
}
int main()
{
int* device_matrix;
int* host_matrix;
int c = 8; //Squared matrix cxc
int device_c = 8;
int device_sum = 0;
int host_sum = 0;
//Allocate host memory
host_matrix = (int*)malloc(sizeof(int)*SIZE);
//Fill the matrix values with 1's
for(auto i = 0; i < SIZE; i++)
host_matrix[i] = 1;
//Allocate device memory
cudaMalloc((void**) &device_matrix,sizeof(int)*SIZE);
cudaMalloc((void**) &device_sum, sizeof(int));
cudaMalloc((void**) &device_c,sizeof(int));
//Fill device_matrix with host_matrix values
cudaMemcpy(&device_matrix,&host_matrix,sizeof(int)*SIZE,cudaMemcpyHostToDevice);
//Initialize device_sum with a 0
cudaMemcpy(&device_sum,&host_sum,sizeof(int),cudaMemcpyHostToDevice);
//Initialize device_c with the correct value
cudaMemcpy(&device_c,&c,sizeof(int),cudaMemcpyHostToDevice);
//4 blocks with 16 threads every single block ¿Is this correct?
add_matrix_values<<<4,16>>>(device_matrix, device_sum,device_c);
cudaMemcpy(&host_sum,&device_sum,sizeof(int),cudaMemcpyDeviceToHost);
std::cout<<"The value is: "<<host_sum<<std::endl;
cudaFree(device_matrix);
free(host_matrix);
return 0;
}
结果必须是 64,但我得到了错误的数字。
migue@migue ~/Escritorio ./program
The value is: 32762
migue@migue ~/Escritorio ./program
The value is: 32608
migue@migue ~/Escritorio ./program
The value is: 32559
我不知道我做错了什么。 它可能是gridSize和blockSize? 或者它可能是 cuda Kernel 中的 i 和 j 操作?
我不太了解这些条款。
有很多问题:
sum
。 您无法以这种方式检索结果。 kernel 对sum
的更改不会反映在调用环境中。 这是一个 C++ 概念,并非特定于 CUDA。 请改用正确分配的指针。cuda
标签上找到许多讨论并行缩减的问题。cudaMalloc
。 您也不要在除指针之外的任何类型的变量上使用cudaMalloc
。cudaMemcpy
的使用不正确。 不需要获取指针的地址。以下代码已解决上述项目:
$ cat t135.cu
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
const int SIZE = 64;
__global__ void add_matrix_values(int* matrix, int *sum, int c)
{
int i = threadIdx.x + blockIdx.x * blockDim.x;
atomicAdd(sum, matrix[i]);
}
int main()
{
int* device_matrix;
int* host_matrix;
int device_c = 8;
int *device_sum;
int host_sum = 0;
//Allocate host memory
host_matrix = (int*)malloc(sizeof(int)*SIZE);
//Fill the matrix values with 1's
for(auto i = 0; i < SIZE; i++)
host_matrix[i] = 1;
//Allocate device memory
cudaMalloc((void**) &device_matrix,sizeof(int)*SIZE);
cudaMalloc((void**) &device_sum, sizeof(int));
//Fill device_matrix with host_matrix values
cudaMemcpy(device_matrix,host_matrix,sizeof(int)*SIZE,cudaMemcpyHostToDevice);
//Initialize device_sum with a 0
cudaMemcpy(device_sum,&host_sum,sizeof(int),cudaMemcpyHostToDevice);
//4 blocks with 16 threads every single block ¿Is this correct?
add_matrix_values<<<4,16>>>(device_matrix, device_sum,device_c);
cudaMemcpy(&host_sum,device_sum,sizeof(int),cudaMemcpyDeviceToHost);
std::cout<<"The value is: "<<host_sum<<std::endl;
cudaFree(device_matrix);
free(host_matrix);
return 0;
}
$ nvcc -o t135 t135.cu
$ cuda-memcheck ./t135
========= CUDA-MEMCHECK
The value is: 64
========= ERROR SUMMARY: 0 errors
$
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.