虽然严格上说,小弟使用CUDA还不到一年,但是这一年中,被这个“怪物”折磨得够呛,今天的只是再普通不过的小插曲,希望这个过程能够给初学者一些启发。
先看一个例子
#include <stdlib.h>
__global__ void test(int x){
Int y=x ;
}
int main(){
int *in;
int len = sizeof(int);
cudaMalloc((void**)&in,len);
test<<<5,256>>>(*in);
cudaFree(in);
}
代码很简短,目的只是想把in的值传给x,当然我在项目中遇到的问题代码远比这复杂,这只是为了要说明这个问题而特意写的。使用nvcc编译后,会提示你y只声明但没有使用,编译会通过,但是你在运行时会提示段错误,段错误一般意味着访问越界或者访问了不能或不应该访问的区域。使用cuda-gdb调试会定位到test<<<5,256>>>(*in)这行,但是我当时左看右看,半天都不明白个所以然。很明显内核是在设备上运行,而in是分配在设备上,应当没有任何问题。为什么会出现段错误,这时我想到了编译器解释<<<>>>语法的过程,首先设置网格和块的大小,再将参数从主机传到设备上,再启动内核等等!我声明的in指针是在主机上,但是值却在设备上,这就是问题所在了。知道问题所在了,就好解决了。各位同学想必有自己的解决方案了吧!我的方法如下,你的方法呢?
#include <stdlib.h>
__global__ void test(int *x){
Int y=*x ;
}
int main(){
int *in;
int len = sizeof(int);
cudaMalloc((void**)&in,len);
test<<<5,256>>>(in);
cudaFree(in);
}