CUDA相关问题汇总

版权声明:本文为博主原创文章,转载请注明链接 https://blog.csdn.net/luroujuan/article/details/86929445

CUDA相关问题汇总

记录一下自己在2018年遇到的一些与CUDA相关的问题,分享给大家,希望能为其他小伙伴提供参考。

PS:如果你遇到的问题不在以下列表之中,可以给我留言,也可以在论坛的CUDA板块中提问,希望大家相互学习,一同进步。

1.环境配置

1.1【问题】在Windows服务器上无法安装CUDA8.0,显示Visual Studio Integration组件失败,其它组件未安装。

分析:由于没能成功安装Visual Studio Integration组件导致其他组件都没能安装成功。

解决:可以暂时不安装Visual Studio Integration组件,在安装时取消它的勾选,便可成功安装其他组件。但这只是在本机上安装了CUDA8.0开发环境,如果需要使用VS进行CUDA程序开发,还是需要将Visual Studio Integration组件安装上。解决方法是将安装包解压,找到相关目录手动复制文件和安装。具体可参考该博客https://blog.csdn.net/zzpong/article/details/80282814,在此不赘述。

2.编译报错

2.1【问题】在kernel核函数中声明某结构体的共享内存变量时,编译报出警告,warning : __shared__ memory variable with non-empty constructor or destructor (potential race between threads)。

分析:因为这个结构体有非空的构造函数,所以在kernel函数一开始每个线程都会调用它的构造函数来初始化共享内存,这样会导致线程间的竞争,比如:先执行完的线程,后续对共享内存做了修改,但修改结果可能会被晚执行的线程覆盖。

解决:1)在__shared__变量声明语句后添加同步语句。

2)改为动态分配共享内存。

2.2【问题】cuda核函数中使用printf,编译报错未定义。

解决方法:包含sdtio.h头文件

2.3【问题】CUDA程序编译时,共享内存报错,declaration is incompatible with previous "***"。

分析:有两种情况会导致这个错误。

1)利用模板时有自定义的数据类型。

2)两个核函数中声明的extern __shared__变量名一样,但类型不一样。

解决:1)参考官方sample,添加sharedmen.cuh文件。

2)修改变量名,使两个名字不一样即可。

 

3.结果错误

3.1【问题】核函数算法编写正确找不出bug,但最终输出的结果与matlab的结果对不上,如何解决。

分析:可能与float数据精度有关系,matlab数据的默认精度是double型的。

解决:将一些变量类型改为double再检查结果是否与matlab对应,如果对应说明核函数编写没有问题,就是float精度的问题。

3.2【问题】Release模式下程序运行结果的精度比Debug模式下的精度低。

分析:CUDA中Release模式下为了提高速度舍弃了精度,默认-fmad=true。

解决:在Release模式下添加“-fmad=false”。

(但此时我们仍要注意,这样只是保证了Debug与Release结果一样,但是与CPU结果仍不一样)

3.3【问题】cuda核函数输出结果一部分正确,一部分错误,且每一部分都是以32个线程为单位。

分析:32个线程(一个线程束)的结果正确,另一个线程束的结果不正确,很可能是因为没有在合适的地方使用__syncthreads()同步函数,导致本线程束的更新结果没有通知到其他线程束中。

解决:在对线程块中共享的数据(比如共享内存,全局内存)进行更新后,要及时进行同步操作。

 

4.运行异常

4.1【问题】在显存中分配结构体,结构体内部的指针又要通过cudaMalloc函数分配显存,运行时报错访问非法内存。

分析:在显存中分配结构体,此时结构体内部的指针是device变量,而cudaMalloc函数只能访问host变量,所以报错。

解决:需要一个host结构体作为中间变量,该变量内的指针通过cudaMalloc函数分配显存,然后将数据传输到该显存,最后再将这个中间变量传给显存中分配的结构体。

4.2【问题】在Windows计算机上利用VS调试CUDA程序时,报错:Nsight Debug CUDA grid launch failed:CUcontext:****。

分析:在该计算机上安装CUDA开发环境时,因为电脑已经安装了显卡驱动且比安装包里的驱动版本新,所以没有勾选安装驱动的选项。Nsight调试失败可能是因为调试工具与显卡驱动版本不兼容。

解决:重新点击CUDA安装软件,这次不用安装CUDA,只需要把驱动相关的选项勾上,即利用安装包里的驱动替换电脑上现有的驱动。

4.3【问题】在Windows计算机上运行CUDA程序时,屏幕黑屏,然后提示“显示器驱动程序已停止相应,并且已经恢复”。

分析:在Windows中很多GPU的驱动模式是WDDM,在该模式下Windows使用GPU与用户交互,所以计算程序不能占用GPU过多的时间,Windows设定了强制延迟界限(默认为2秒),这意味着如果CUDA核函数运行时间超多这个界限,系统就会弹出上面的提示,然后重新启动驱动程序。(如果GPU的驱动模式为TCC,则没有这个限制)

解决:1)查看自己的程序是否在Debug模式下运行,改为Release模式程序运行时间会减少很多,可能会降到2ms以内。

2)修改延迟界限(TDR)为更大的值,或者关闭延迟界限。方法为:打开Nsight Monitor程序,选择“Nsight Monitor Options”,修改“WDDM TDR Delay”为20或更大的值,或者修改“WDDM TDT enable”为False。

3)如果你的GPU支持TCC驱动模式,利用nvidia-smi工具进行修改。

4.4【问题】在调试CUDA程序的时候,电脑经常蓝屏死机。

分析:通过nvidia-smi检查GPU状态信息,发现GPU温度过高,达到90度以上。电脑蓝屏关机应该是由于GPU温度过高导致的。

解决:检查服务器机箱发现,开机挡板的纱网不透气,影响机箱里风扇抽风散热,将挡板上的纱网拆卸,清灰之后,可正常散热。

4.5【问题】两台Windows计算机,在一台机器上编译生成的GPU程序,在另一台上运行结果不正确。

分析:打开程序中输出日志的功能,发现运行第一个核函数就提示:invalid device function。检查核函数编写并没有问题。最后发现项目制定的计算能力集是“compute_37,sm_37”,第一台机器上的P100的计算能力集达到6.0,兼容3.7,所以可以正常运行。而另一台上的GT730的计算能力集是3.5,不兼容3.7,所以会提示错误且不能正确运行。

解决:将项目的计算能力集修改为3.5或者更低。

注:另外,我发现GT730在运行3.7的程序时,有时也不会报错,但运行结果不正确。将项目的计算能力集改为“compute_37,sm_37;compute_35,sm_35”时,程序的运行结果可能仍然不正确,这时候需要将计算能力集只设置为“compute_35,sm_35”

本文为博主原创文章,转载请注明链接 https://blog.csdn.net/luroujuan/article/details/86929445

猜你喜欢

转载自blog.csdn.net/luroujuan/article/details/86929445
今日推荐