CUDA编程主要做的就是和GPU打交道,在和这样的一个陌生的家伙交流之前,我们需要做的就是先得认识和熟悉这个家伙。
在深入研究如何编写设备代码之前,我们需要通过某种机制来判断计算机中当前有哪些设备,以及每个设备都支持哪些功能。幸运的是,可以通过一个非常简单的接口来获得这种信息。首先,我们希望知道在系统中有多少个设备是支持CUDA架构的,并且这些设备能够运行基于CUDA C编写的核函数。要获得CUDA设备的数量.可以调用cudaGetDeviceCount()。这个函数的作用从色的名字就可以看出来。在调用cudaGetDeviceCount()后,可以对每个设备进行迭代、井查询各个设备的相关信息。CUDA运行时将返回一个cudaDevice Prop类型的结构,其中包含了设备的相关属性。我们可以获得哪些属性?从CUDA 3.0开始,在cudaDeviceProp结构中包含了以下信息:
struct cudaDeviceProp
{
char name[256]; //标识设备的ASCII字符串
size_t totalGlobalMem; //设备上全局内存的总量,单位为字节
size_t sharedMemPerBlock; //在一个线程块(Block)中可使用的共享内存总量,单位为字节
int regsPerBlock; //每个线程块中可用的32位寄存器数量
int warpSize; //在一个线程束(warp)中包含的线程数量
size_t memPitch; /在内存复制中最大的修正量(Pitch),单位为字节
int maxThreadsPerBlock; //在一个线程块中包含的最大线程数目
int maxThreadsDim[3]; //在多维线程块数组中,每一维包含的最大线程数量
int maxGridSize [3]; //在一个线程格(Grid)中,每一维可以包含的线程块的数量
size_t totalConstMem; //常量内存的总量
int major; //设备计算功能集的主版本号
int minor; //设备计算功能集的次版本号
int clockRate; //
size_t textureAlignment; //设备的纹理对齐要求
int deviceoverlap; //一个布尔类型值,表示设备是否可以同时执行一个cudaMemory()调用和一个核函数调用
int multiProcessorCount; //设备上多处理器的数量
int kernelExecTimeoutEnabled; //一个布尔值,表示该设备上执行的核函数是否存在运行时限制
int integrated; //一个布尔值,表示设备是否是一个集成的GPU
int canMapHostMemory; //一个布尔值,表示设备是否将主机内存映射到cuda设备地址空间
int computeMode; //表示设备的计算模式:默认,独占或禁止
int maxTexture1D; //一维纹理的最大大小
int maxTexture2D[2]; //二维纹理的最大维数
int maxTexture3D[3]; //三维纹理的最大维数
int maxTexture2DArray[3]; //二维纹理数组的最大维数
int concurrentKernels ; //一个布尔值,表示设备是否支持在同一个上下文中同时执行多个核函数
};
设备属性的使用
通过上面的结构体,我们大致了解了设备的属性,然后我们就可以通过这个结构体来查询设备属性了。可能会有人问,到底我们需要这些设备属性来干嘛,别着急,以后在编写相关性能优化的代码的时候,就知道了解这些属性的好处了。现在我们只需要知道方法就可以了。
首先我们可以通过两个函数,第一个就是上面的cudaGetDeviceCount()来选择设备,然后循环地通过getDeviceProperties()来获得设备的属性,之后我们就可以通过这样的一个结构体变量将设备的属性值获取出来。
#include <cuda_runtime.h>
#include <iostream>
using namespace std;
int main()
{
cudaDeviceProp prop;
int count;
cudaGetDeviceCount(&count);
for(int i = 0 ; i < count ; i++)
{
cudaGetDeviceProperties(&prop,i);
cout<<"the information for the device : "<<i<<endl;
cout<<"name:"<<prop.name<<endl;
cout<<"the memory information for the device : "<<i<<endl;
cout<<"total global memory:"<<prop.totalGlobalMem<<endl;
cout<<"total constant memory:"<<prop.totalConstMem<<endl;
cout<<"threads in warps:"<<prop.warpSize<<endl;
cout<<"max threads per block:"<<prop.maxThreadsPerBlock<<endl;
cout<<"max threads dims:"<<prop.maxThreadsDim[0]<<" "<<prop.maxThreadsDim[1]<<
" "<<prop.maxThreadsDim[2]<<endl;
cout<<"max grid dims:"<<prop.maxGridSize[0]<<" "<<
prop.maxGridSize[1]<<" "<<prop.maxGridSize[2]<<endl;
}
return 0;
}
我这边只是获取一部分的属性值,只是和大家介绍一下,具体的属性值可以按照这样的方法来获取。