cuda编程需要注意的

在编写cuda代码时,由于并行处理都是在GPU端,如果在设备端代码中不加捕捉异常的话,即使在GPU端运行出错了,你也不会知道出错了。GPU端的代码又不好调试,因此知道怎么在GPU端的代码添加异常捕捉是非常有必要的,当然这和在cup端的不太一样。以下是一段异常捕捉代码,供大家参考:

void checkCUDAError(const char *msg)   
{   
    cudaError_t err = cudaGetLastError();   
    if( cudaSuccess != err)    
    {   
        fprintf(stderr, "Cuda error: %s: %s.\n", msg,    
                                  cudaGetErrorString( err) );   
        exit(EXIT_FAILURE);   
    }                            
}  

在代码前端,要记得声明函数,想要在哪里捕捉错误信息,就在哪里调用函数。例如:

compare<<>>(data,d_inf,d_result,d);
     checkCUDAError("kernel invocation"); 

cudaMemcpy(h_result, d_result, sizeof(unsigned long)*row* r_width ,cudaMemcpyDeviceToHost);
   checkCUDAError("memcpy"); 

这里要注意的是CPU和GPU是异步执行的,因此在调用GPU端的compare函数时,即使在后面加了异常捕捉,也是捕捉不到错误的,因为cpu不等GPU端的代码执行完就先往下执行了,因此要等GPU端的代码执行完再捕捉才能捕捉的到。
      下面我跟大家分享一个我觉得大家在编程时需要注意的问题以及解决方案,以免大家重蹈覆辙,造成不必要的困扰。
      我编写的cuda程序在运行小数据的程序时,运行正确,但是运行大数据时,结果就不对了。于是便疯狂寻找程序本身的原因,以为是内存不足,因为显存只有1G,确实需要小心使用。但是尽管把程序的显存使用优化到极致,还是运行不正确。最后加了异常捕捉,出现了如下错误:
  
       出现这个错误的原因是由于机器的显卡在运行CUDA程序的同时,也在承担着机器的图形界面显示,因此不可能让CUDA程序无时间限制地一直占用GPU,这一项在GPU的参数中显示为:

一旦CUDA程序运行超过5秒钟,GPU就会终止程序的运行。
解决这个错误有两种方法:
1.在cpu中多次调用kernel函数,也就是把大数据分割成小数据,以保证每个kernel在5秒钟之内能运行完。
2.关闭GPU的显示功能,仅供计算使用,这样就会有时间的限制。
在Linux端,由于我们的显卡是专门做计算的,因此适合选择第2种方法。
目前我研究出的方法:在运行CUDA程序前,利用命令把图形界面关闭。命令:sudo stop gdm
当然不排除还有其他的硬性的办法,例如修改配置文件等等。
经过这番修改之后,运行cuda程序就没有时间限制了~

你可能感兴趣的:(并行计算)