Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CUDA如何将设备ID分配给GPU?_Cuda_Gpu_Gpgpu_Nvidia - Fatal编程技术网

CUDA如何将设备ID分配给GPU?

CUDA如何将设备ID分配给GPU?,cuda,gpu,gpgpu,nvidia,Cuda,Gpu,Gpgpu,Nvidia,当一台计算机有多个支持CUDA的GPU时,每个GPU都分配一个设备ID。默认情况下,CUDA内核在设备ID 0上执行。您可以使用cudaSetDevice(int-device)选择其他设备 假设我的机器中有两个GPU:GTX 480和GTX 670CUDA如何决定哪个GPU是设备ID 0和哪个GPU是设备ID 1? CUDA如何分配设备ID的想法(只是头脑风暴): 计算能力的降序 PCI插槽号 设备添加到系统的日期/时间(刚刚添加到计算机的设备的ID号更高) 动机:我正在研究一些HPC

当一台计算机有多个支持CUDA的GPU时,每个GPU都分配一个
设备ID
。默认情况下,CUDA内核在
设备ID 0
上执行。您可以使用
cudaSetDevice(int-device)
选择其他设备

假设我的机器中有两个GPU:GTX 480和GTX 670CUDA如何决定哪个GPU是
设备ID 0
和哪个GPU是
设备ID 1


CUDA如何分配设备ID的想法(只是头脑风暴):

  • 计算能力的降序
  • PCI插槽号
  • 设备添加到系统的日期/时间(刚刚添加到计算机的设备的ID号更高)


动机:我正在研究一些HPC算法,我正在为几个GPU进行基准测试和自动调整。我的处理器有足够的PCIe通道以全带宽将cudaMemcpys驱动到3 GPU。因此,我计划在我的计算机中只保留3个GPU,而不是不断地在我的计算机中交换GPU。我希望能够预测在计算机中添加或更换某些GPU时会发生什么情况。

CUDA选择最快的设备作为设备0。因此,当您交换GPU时,顺序可能会完全改变。根据其PCI总线id选择GPU可能更好,使用:

cudaError_t cudaDeviceGetByPCIBusId ( int* device, char* pciBusId )
   Returns a handle to a compute device.

cudaError_t cudaDeviceGetPCIBusId ( char* pciBusId, int  len, int  device )
   Returns a PCI Bus Id string for the device.
或CUDA驱动程序API
cuDeviceGetByPCIBusId
cuDeviceGetPCIBusId

但在我看来,知道哪个设备是哪个设备最可靠的方法是使用或使用
nvmlDeviceGetUUID
获取每个设备的唯一标识符(UUID),然后使用
nvmlDeviceGetPciInfo

将CUDA设备与pciBusId进行匹配

在具有多个GPU的计算机上运行CUDA程序时,默认情况下,CUDA内核将在主图形卡插槽中安装的任何GPU上执行

此外,在上的讨论表明,CUDA通常不会将“最佳”卡映射到设备0

编辑


今天,我安装了一台电脑,电脑上有一块用于计算的特斯拉C2050卡和一块用于在前两个PCI-E插槽之间切换位置的8084 GS卡。我使用了deviceQuery并注意到GPU
0
始终位于第一个PCI插槽中,GPU
1
始终位于第二个PCI插槽中。我不知道这是否是一个一般性的陈述,但它证明了我的系统GPU不是根据它们的“功率”,而是根据它们的位置进行编号。

将环境变量
CUDA\u DEVICE\u ORDER
设置为:

export CUDA_DEVICE_ORDER=PCI_BUS_ID

然后GPU ID将按pci总线ID排序。

我找到的最佳解决方案(在
tensorflow==2.3.0
中测试)是在可能导入的任何内容之前添加以下内容:

import os
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"]="0,3"  # specify which GPU(s) to be used

这样,TensorFlow命令GPU的顺序将与工具(如
nvidia smi
nvtop

所报告的“最快”的顺序相同。您的意思是在时钟速度方面吗?一些试探法用于估计GPU的理论速度。它们考虑了芯片结构、时钟速度、驱动程序型号(在windows TCC上是首选)。目前,我的机器中有3个支持CUDA的GPU:一个GTX680、一个GTX9800(一个古老的、速度较慢的GPU,我只用于图形)和一个C2050。奇怪的是,GTX9800得到的数字低于C2050。。。奇怪。只有索引为0的GPU是最快的。其余索引不按速度排序。GTX 9800是否有索引0?如果不是,那么一切都按预期进行。不,GTX9800没有索引0。现在更有意义了,我同意。我曾经有过这样的例子,一台机器有一个现代的GTX6xx开普勒和一个古老的G80,而设备0就是G80。相反的情况也发生在我身上。“PCIe插槽顺序”的解释听起来很合理。除了尝试为PCIe_3兼容的GPU保留PCIe_3插槽外,我没有太多注意我使用的PCIe插槽顺序。使用此设置,CUDA设备id与nvidia smi的输出一致!在我看来,这是在多gpu机器上进行机器学习的必备条件。这如何解释CUDA以何种顺序枚举设备,这就是问题所在?因为OP要求“我希望能够预测当我在计算机中添加或替换某些gpu时会发生什么”,我的回答正好做到了这一点。