3.4_设备属性的使用

3.4 设备属性的使用

除非是编写一个需要输出每个支持CUDA的显卡的详细属性的应用程序,否则我们是否需要了解系统中每个设备的属性?作为软件开发人员,我们希望编写出的软件是最快的,因此可能需要选择拥有最多处理器的GPU来运行代码。或者,如果核函数与CPU之间需要进行密集交互,那么可能需要在集成的GPU上运行代码,因为它可以与CPU共享内存。这两个属性都可以通过CUDAGetDeviceProperties()来查询。

假设我们正在编写一个需要使用双精度浮点计算的应用程序。在快速翻阅《NVIDIA CUDA Programming Guide》的附录A后,我们知道计算功能集的版本为1.3或者更高的显卡才能支持双精度浮点数学计算。因此,要想成功地在应用程序中执行双精度浮点运算,GPU设备至少需要支持1.3或者更高版本的计算功能集。

根据在cusdaGetDeviceCount()和cusdaGetDeviceProperties()中返回的结果,我们可以对每个设备进行迭代,并且查找主版本号大于1,或者主版本号为1且次版本号大于等于3的设备。但

是,这种迭代操作执行起来有些繁琐,因此CUDA运行时提供了一种自动方式来执行这个迭代操作。首先,找出我们希望设备拥有的属性并将这些属性填充到一个CUDADeviceProp结构。

cudaDeviceProp prop;  
memset( &prop, 0, sizeof(udaDeviceProp));  
prop major = 1;  
prop.minor = 3;

在填充完cusdaDeviceProp结构后,将其传递给cusdaChooseDevice(),这样CUSDA运行时将查找是否存在某个设备满足这些条件。cusdaChooseDevice()函数将返回一个设备ID,然后我们可以将这个ID传递给cusdaSetDevice()。随后,所有的设备操作都将在这个设备上执行。

include"../common/book.h"   
int main(void){ CUDADevicePropprop; intdev; HANDLE_ERROR(cudaGetDevice(&dev)); printf("IDofcurrentCUDA device:%d\n",dev);memset&prop,0,sizeof(cudaDeviceProp)); prop major  $= 1$  · prop.minor  $= 3$  : HANDLE_ERROR(cudaChooseDevice(&dev,&prop)); printf("IDofCUDA deviceclosest to revision1.3:%d\n",dev); HANDLE_ERROR(cudaSetDevice(dev));   
}

当前,在系统中拥有多个GPU已是很常见的情况。例如,许多NVIDIA主板芯片组都包含了集成的并且支持CUDA的GPU。当把一个独立的GPU添加到这些系统中时,那么就形成了一个多GPU的平台。而且,NVIDIA的SLI(Scalable Link Interface,可伸缩链路接口)技术使得多个独立的GPU可以并排排列。无论是哪种情况,应用程序都可以从多个GPU中选择最适合的GPU。如果应用程序依赖于GPU的某些特定属性,或者需要在系统中最快的GPU上运行,那么你就需要熟悉这个API,因为CUDA运行时本身并不能保证为应用程序选择最优或者最合适的GPU。