3.3_查询设备
3.3 查询设备
由于我们希望在设备上分配内存和执行代码,因此如果在程序中能够知道设备拥有多少内存以及具备哪些功能,那么将非常有用。而且,在一台计算机上拥有多个支持CUDA的设备也是很常见的情形。在这些情况中,我们希望通过某种方式来确定使用的是哪一个处理器。
例如,在许多主板中都集成了NVIDIA图形处理器。当计算机生产商或者用户将一块独立的图形处理器添加到计算机时,那么就有了两个支持CUDA的处理器。某些NVIDIA产品,例如 GeForce GTX 295,在单块卡上包含了两个GPU,因此使用这类产品的计算机也就拥有了两个支持CUDA的处理器。
在深入研究如何编写设备代码之前,我们需要通过某种机制来判断计算机中当前有哪些设备,以及每个设备都支持哪些功能。幸运的是,可以通过一个非常简单的接口来获得这种信息。首先,我们希望知道在系统中有多少个设备是支持CUDA架构的,并且这些设备能够运行基于CUDA C编写的核函数。要获得CUDA设备的数量,可以调用CUDAGetDeviceCount()。这个函数的作用从它的名字就可以看出来。
int count;
HANDLE_ERROR(udaGetDeviceCount(&count));在调用CUDAGetDeviceCount()后,可以对每个设备进行迭代,并查询各个设备的相关信息。CUDA运行时将返回一个CUDADeviceProp类型的结构,其中包含了设备的相关属性。我们可以获得哪些属性?从CUDA3.0开始,在CUDADeviceProp结构中包含了以下信息:
struct CUDADeviceProp {
char name[256];
size_t totalGlobalMem;
size_t sharedMemPerBlock;
int regsPerBlock;
int warpSize;
size_t memPitch;
int maxThreadsPerBlock;
int maxThreadsDim[3];
int maxGridSize[3];
size_t totalConstMem;
int major;
int minor;
int clockRate;
size_t textureAlignment;int deviceOverlap;
int multiProcessorCount;
int kernelExecTimeoutEnabled;
int integrated;
int canMapHostMemory;
int computeMode;
int maxTexture1D;
int maxTexture2D[2];
int maxTexture3D[3];
int maxTexture2DArray[3];
int concurrentKernels;其中,有些属性的含义是显而易见的,其他属性的含义如下所示(见表3.1)。
表3.1 CUDA设备属性
就目前而言,我们不会详细介绍所有这些属性。事实上,在上面的列表中没有给出属性的一些重要细节,因此你需要参考《NVIDIA CUDA Programming Guide》以了解更多的信息。当开始编写应用程序时,这些属性会非常有用。但就目前而言,我们只是给出了如何查询每个设备并且报告设备的相应属性。下面给出了对设备进行查询的代码:
include"../common/book.h"
int main(void){ CUDADevicePropprop; int count; HANDLE_ERROR( CUDAGetDeviceCount(&count)); for(int $\mathrm{i} = 0$ ;i<count;i++){ HANDLE_ERROR( CUDAGetDeviceProperties(&prop,i)); //对设备的属性执行某些操作 }在知道了每个可用的属性后,接下来就可以将注释“对设备的属性执行某些操作”替换为一些具体的操作:
include"../common/book.h"
int main(void){ CUDADeviceProp prop; int count; HANDLE_ERROR( CUDAGetDeviceCount(&count)); for(int $\mathrm{i} = 0$ ;i< count;i++){ HANDLE_ERROR( CUDAGetDeviceProperties(&prop,i)); printf("---General Information for device&d----\n",i); printf("Name:%s\n",prop.name); printf("Compute capability:%d.%d\n",prop major,prop.minor); printf("Clock rate:%d\n",prop.clockRate); printf("Device copy overlap:"); if(prop_deviceOverlap) printf("Enabled\n"); else printf("Disabled\n"); printf("Kernel execution timeout:"); if(prop_kernelExecTimeoutEnabled) printf("Enabled\n");else printf("Disabled\n"); printf( "---Memory Information for device $\& d - - - \backslash n ^ { \prime \prime }$ ,i); printf("Total global mem: %ld\n",prop.totalGlobalMem); printf("Total constant Mem: %ld\n",prop.totalConstMem); printf("Max mem pitch: %ld\n",prop.memPitch); printf("Texture Alignment: %ld\n",prop.textureAlignment); printf("---MP Information for device $\& d - - - \backslash n ^ { \prime \prime }$ ,i); printf("Multiprocessor count: %d\n", prop.multiProcessorCount); printf("Shared mem per mp: %ld\n",prop.sharedMemPerBlock); printf("Registers per mp: %d\n",prop.regsPerBlock); printf("Threads in warp: %d\n",prop.warpSize); printf("Max threads per block: %d\n", prop.maxThreadsPerBlock); printf("Max thread dimensions: (%d, %d, %d)\n", prop.maxThreadsDim[0], prop.maxThreadsDim[1], prop.maxThreadsDim[2]); printf("Max grid dimensions: (%d, %d, %d)\n", prop.maxGridSize[0], prop.maxGridSize[1], prop.maxGridSize[2]); printf("\n"); }