我是CUDA的新手,正在从事矢量加法的第一个练习
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
// Compute vector sum C = A+B
//CUDA kernel. Each thread performes one pair-wise addition
__global__ void vecAddKernel(float *A, float *B, float *C, int n)
{
//Get our global thread ID
int i = blockDim.x*blockIdx.x+threadIdx.x;
if (i<n) C[i] = A[i] + B[i];
}
int main(int argc, char* argv[])
{
//Size of vectors
int n = 100000;
int size = n * sizeof(float);
//Host input vectors
float *h_A, *h_B;
//Host output vector
float *h_C;
//Device input vectors
float *d_A, *d_B;
//Device output vector
float *d_C;
//Allocate memory for each vector on host
h_A = (float*)malloc(sizeof(size));
h_B = (float*)malloc(sizeof(size));
h_C = (float*)malloc(sizeof(size));
//Allocate memory for each vector on GPU
cudaMalloc( (void **) &d_A, size);
cudaMalloc( (void **) &d_B, size);
cudaMalloc( (void **) &d_C, size);
//Copy host vectors to device
cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
int blockSize, gridSize;
//Number of threads in each block
blockSize = 1024;//Execute the kernel
vecAddKernel<<<gridSize,blockSize>>>(d_A, d_B, d_C, n);
//Synchronize threads
cudaThreadSynchronize();
//Copy array back to host
cudaMemcpy( h_C, d_C, size, cudaMemcpyDeviceToHost );
//Release device memory
cudaFree(d_A);
cudaFree(d_B);
cudaFree(d_C);
//Release host memory
free(h_A);
free(h_B);
free(h_C);
return 0;
}
编译成功,但是在运行代码时我得到:`Segmentation fault(core dumped)。我看不出问题出在哪里。我尝试使用nvprof,但以任何方式都没有帮助。 谁能帮助我找出我在哪里犯了错误?
答案 0 :(得分:1)
这些陈述是不正确的:
h_A = (float*)malloc(sizeof(size));
h_B = (float*)malloc(sizeof(size));
h_C = (float*)malloc(sizeof(size));
它们应该是:
h_A = (float*)malloc(size);
h_B = (float*)malloc(size);
h_C = (float*)malloc(size);
malloc
采用一个参数,该参数是要分配的字节大小。因此,当您传递值size
时,您传递的值是400000,这是正确的。当您传递值sizeof(size)
时,您传递的值是size
变量的大小(以字节为单位)(即size
变量本身占用多少空间来存储其数量) )。那是一个4的值(int
是4个字节)。
因此,当您进行cudaMemcpy
的操作时,例如说h_A
并要求向h_A
所指的内容传输400000个字节,而您仅提供了4个字节的分配在那里(无论它指向何处),您都将使其超载并出现段错误。
这与CUDA无关。
顺便说一句,nvprof
并不是解决此问题的正确工具。 nvprof
是分析器,它希望要分析的代码在功能上是正确的。您无需使用nvprof
来调试此类问题。它不是调试器。
由于这纯粹是一个主机代码问题(就像所有seg错误一样,即使在CUDA中也是如此),因此您可以使用gdb
之类的主机调试器来调试它。当然,您可以类似地使用类似cuda-gdb
的工具来调试它。同样,如果您在Windows上,则例如内置调试器。视觉工作室。
最后,对于解决此特定问题并不会有多大帮助,但是我始终建议,只要您遇到CUDA代码问题,都应使用proper CUDA error checking并使用cuda-memcheck
运行代码。