3.2.3 多设备
主机系统上可以有多个设备。可以枚举这些设备,也可以查询他们的属性,可以选择它们中的一个执行内核。
多个主机线程可以在同一个设备上执行设备代码,但是设计成在某个既定时间,一个主机线程只能在一个设备上执行设备代码。这样,多个主机线程在多个设备上执行设备代码。在某个主机线程内,使用CUDA运行时创建的任何CUDA资源不能被其它线程使用。
下面的例子代码枚举了系统中的所有设备同时检索了它们的属性。也确定了支持CUDA的设备的数目。
cudaGetDeviceCount(&deviceCount);
int device;
for (device = 0; device < deviceCount; ++device) {
cudaDeviceProp deviceProp;
cudaGetDeviceProperties(&deviceProp, device);
if (dev == 0) {
if (deviceProp.major == 9999 && deviceProp.minor == 9999)
printf("There is no device supporting CUDA.\n");
else if (deviceCount == 1)
printf("There is 1 device supporting CUDA\n");
else
默认情况下,只要一个非运行时设备管理函数调用(例外参见3.6节),主机线程隐式的使用0号设备。可以通过调用cudaSetDevice()函数来启用其它的设备。一旦设备启用,无论是显式的还是隐式的,其后对cudaSetDevice()的调用都会失败,除非调用了cudaThreadExit()。cudaThreadExit()清理所有与主机调用线程相关的运行相关的资源。随后的运行时API调用将重新初始化运行时。
3.2.4 纹理存储器
CUDA支持纹理硬件的一个子集,GPU为图形使用这个子集访问纹理存储器。如5.3.2.5节所示,从纹理存储器而不是全局存储器中读数据有许多性能好处。
如B.8节所示,在内核中,调用纹理获取设备函数读纹理存储器。纹理获取的第一个参数指定的对象称为纹理参考。
纹理参考定义了被获取的纹理存储器部分。如3.2.4.3节所述,纹理参考在被内核使用之前,必须使用运行时函数绑定到存储器的某个区域,这个区域称为纹理。多种不同的纹理参考可能绑定到同一纹理或者绑定到存储器重叠的纹理。
纹理参考有许多属性。其中之一就是维数,维数指定纹理是作为一维的数组使用一个纹理坐标、二维数组使用两个纹理坐标、还是三维数组使用三维坐标来寻址。数组的元素称为texels,是纹理参考元素的简称。
其它属性定义纹理获取的输入输出数据类型,也包括怎样解释输入坐标和要做那些处理。
纹理可以是线性存储器的任何一个区域或者一个CUDA数组。
CUDA数组是为纹理获取优化的不透明的存储器层次。它们可以是一维的,二维的或三维的,也可由多个元素组成,每个元素可有1,2或4个组件,这些组件可能是有符号或无符号8,16或32位整形,16位浮点(目前只在驱动API中支持),或32位浮点。CUDA数组只能在内核中通过纹理获取读取,且只能绑定到和已打包的组件数目相同的纹理参考。