从bug到非bug-记一次debug之旅

虽然严格上说,小弟使用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);
}