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。