WSL环境运行CUDA代码报Segmentation fault 疑似cudaMalloc问题如何解决
报错原因
你遇到的*Segmentation fault (core dumped)*错误并非由cudaMalloc本身的调用错误导致,核心问题是违反了CUDA的内存访问规则:
cudaMalloc申请的是GPU显存上的内存空间,返回的指针是设备地址,仅能在GPU内核代码中直接访问,主机CPU没有权限直接读写该地址指向的空间。你代码中直接在主机侧的for循环对cudaMalloc返回的a、b、c指针做赋值操作,属于CPU非法访问GPU地址,直接触发段错误。
修复步骤
- 分别定义主机侧、设备侧两类指针,主机侧指针对应CPU可直接访问的内存,设备侧指针对应GPU显存地址
- 主机侧使用标准
malloc申请内存,完成数据初始化后,调用cudaMemcpy接口将数据从主机内存拷贝到GPU显存 - 内核执行完成后,调用
cudaMemcpy将GPU上的计算结果拷贝回主机内存,再在主机侧做打印等操作 - 释放内存时需分别调用
free释放主机内存、cudaFree释放设备显存
修复后的可运行代码
#include<stdio.h> #define SIZE 20 __global__ void VectorAdd(int *a,int *b,int *c,int n){ int i = threadIdx.x; if(i<n) c[i]=a[i]+b[i]; } int main(){ // 主机侧可直接访问的指针 int *h_a, *h_b, *h_c; // GPU设备侧指针 int *d_a,*d_b,*d_c; // 申请主机内存 h_a = (int*)malloc(SIZE * sizeof(int)); h_b = (int*)malloc(SIZE * sizeof(int)); h_c = (int*)malloc(SIZE * sizeof(int)); // 申请GPU显存 cudaMalloc((void**)&d_a,SIZE *sizeof(int)); cudaMalloc((void**)&d_b, SIZE *sizeof(int)); cudaMalloc((void**)&d_c,SIZE *sizeof(int)); // 仅在主机侧初始化数据 for (int i=0;i<SIZE;i++){ h_a[i]=i; h_b[i]=i; h_c[i]=0; } // 主机数据拷贝到GPU cudaMemcpy(d_a, h_a, SIZE*sizeof(int), cudaMemcpyHostToDevice); cudaMemcpy(d_b, h_b, SIZE*sizeof(int), cudaMemcpyHostToDevice); cudaMemcpy(d_c, h_c, SIZE*sizeof(int), cudaMemcpyHostToDevice); VectorAdd<<<1, SIZE>>>(d_a,d_b,d_c,SIZE); cudaDeviceSynchronize(); // 计算结果从GPU拷回主机 cudaMemcpy(h_c, d_c, SIZE*sizeof(int), cudaMemcpyDeviceToHost); // 主机侧打印结果 for(int i=0;i<SIZE;i++){ printf("%d \n",h_c[i]); } // 分别释放主机和GPU内存 free(h_a); free(h_b); free(h_c); cudaFree(d_a); cudaFree(d_b); cudaFree(d_c); return 0; }
WSL环境额外检查项
- 确认WSL内安装的CUDA Toolkit版本和Windows宿主系统的NVIDIA显卡驱动版本匹配,否则可能出现CUDA接口调用失败问题
- 可以在WSL终端执行
nvidia-smi验证驱动适配情况,正常执行无报错说明基础环境正常
内容的提问来源于stack exchange,提问作者Gabi Alex
相关产品推荐
相关产品推荐

