Abstract: 本文只介绍一个功能,如何获取设备(一个或多个)信息
Keywords: CUDA Device Information
GPU设备信息
今天跑了一天,然后晚上写了今天的代码,虽然都是printf的内容,用到的api就那么一两个,但是我还是自己打了一遍,算是深入学习一下。
我们用CUDA的时候一般有两种情况,一种自己写完自己用,使用本机或者已经确定的服务器,这时候我们只要查看说明书或者配置说明就知道用的什么型号的GPU,以及GPU的所有信息,但是如果我们写的程序是通用的程序或者框架,我们在使用CUDA前要先确定当前的硬件环境,这使得我们的程序不那么容易因为设备不同而崩溃,本文介绍两种方法,第一种适用于通用程序或者框架,第二种适合查询本机或者可登陆的服务器,并且一般不会改变,那么这时候用一条nvidia驱动提供的指令查询设备信息就很方便了。
API查询GPU信息
在软件内查询信息,用到如下代码:
1 |
|
主要用到了下面API,了解API的功能最好不要看博客,因为博客不会与时俱进,要查文档,所以我这里不挨个解释用法,对于API的不了解,解决办法:查文档,查文档,查文档!
1 | cudaSetDevice |
1 | cudaGetDeviceProperties |
1 | cudaDriverGetVersion |
1 | cudaRuntimeGetVersion |
1 | cudaGetDeviceCount |
运行的效果如下:
这里面很多参数是我们后面要介绍的,而且每一个都对性能有影响:
- CUDA驱动版本
- 设备计算能力编号
- 全局内存大小(1.95G,原文有错误,写成MBytes了)
- GPU主频
- GPU带宽
- L2缓存大小
- 纹理维度最大值,不同维度下的
- 层叠纹理维度最大值
- 常量内存大小
- 块内共享内存大小
- 块内寄存器大小
- 线程束大小
- 每个处理器硬件处理的最大线程数
- 每个块处理的最大线程数
- 块的最大尺寸
- 网格的最大尺寸
- 最大连续线性内存
上面这些都是后面要用到的关键参数,这些会严重影响我们的效率。后面会一一说到,不同的设备参数要按照不同的参数来使得程序效率最大化,所以我们必须在程序运行前得到所有我们关心的参数。
NVIDIA-SMI
nvidia-smi是nvidia驱动程序内带的一个工具,可以返回当前环境的设备信息:
这个命令可以加各种参数,当然参数你要查文档查文档查文档:
利用下面这个参数可以精简上面那么一大堆的信息,而这些可以在脚本中帮我们得到设备信息,比如我们可以写通用程序时在编译前执行脚本来获取设备信息,然后在编译时固化最优参数,这样程序运行时就不会被查询设备信息的过程浪费资源。
也就是我们可以用一下两种方式编写通用程序:
- 运行时获取设备信息:
- 编译程序
- 启动程序
- 查询信息,将信息保存到全局变量
- 功能函数通过全局变量判断当前设备信息,优化参数
- 程序运行完毕
- 编译时获取设备信息
- 脚本获取设备信息
- 编译程序,根据设备信息调整固化参数到二进制机器码
- 运行程序
- 程序运行完毕
详细信息使用
1 | nvidia-smi -q -i |
可以得到如下信息,过于详细,不贴图了:
1 | ==============NVSMI LOG============== |
下面这些nvidia-smi -q -i 0 的参数可以提取我们要的信息(这样我们就不需要用正则表达式了,😆)
- MEMORY
- UTILIZATION
- ECC
- TEMPERATURE
- POWER
- CLOCK
- COMPUTE
- PIDS
- PERFORMANCE
- SUPPORTED_CLOCKS
- PAGE_RETIREMENT
- ACCOUNTING
比如我们想得到内存信息:
1 | nvidia-smi -q -i 0 -d MEMORY |
得到如下:
多设备时,我们只要把上面的0改成对应的设备号就好了。
总结
今天没有理论行的东西,都是技术层面的,没存,技术问题最好的解决方法就是查文档,而原理部分就要看书看教程了,至此CUDA的编程模型大概就是这些了,核函数,计时,内存,线程,设备参数,这些足够能写出比CPU块很多的程序了,但是追求更快的我们要深入研究每一个细节,从下一篇开始,我们深入硬件,研究背后的秘密
待续。。。
v1.5.2