我当前正在将算法移植到两个GPU。该硬件具有以下设置:在NUMA机器上使用CUDA进行多GPU编程
- 两个CPU作为NUMA系统,因此主内存分割为两个NUMA 节点。
- 每个GPU物理连接到其中一个GPU。 (每个PCIe控制器有一个GPU)
我在主机上创建了两个线程来控制GPU。线程每个绑定到一个NUMA节点,即每个线程都在一个CPU套接字上运行。我如何确定GPU的数量,以便我可以使用cudaSetDevice()
选择直接连接的GPU?
我当前正在将算法移植到两个GPU。该硬件具有以下设置:在NUMA机器上使用CUDA进行多GPU编程
我在主机上创建了两个线程来控制GPU。线程每个绑定到一个NUMA节点,即每个线程都在一个CPU套接字上运行。我如何确定GPU的数量,以便我可以使用cudaSetDevice()
选择直接连接的GPU?
正如我在评论中提到的,这是一种CPU GPU亲和力。这是一个我一起入侵的bash脚本。我相信它会在RHEL/CentOS 6.x OS上提供有用的结果。它可能无法在许多旧的或其他Linux发行版上正常工作。您可以运行这样的脚本:
./gpuaffinity > out.txt
然后,您可以在您的程序读取out.txt
,以确定哪些逻辑CPU内核对应的GPU哪个。例如,NUMA桑迪桥系统具有两个6核处理器和4个GPU上,示例输出可能看起来像这样:
0 03f
1 03f
2 fc0
3 fc0
该系统4个GPU,编号从0到3。每个GPU数字后跟通过“核心面具”。核心掩码对应于与该特定GPU“接近”的核心,表示为二进制掩码。因此对于GPU 0和1,系统中的前6个逻辑内核(03f二进制掩码)最接近。对于GPU 2和3,系统中的后6个逻辑内核(fc0二进制掩码)最接近。
您可以读取程序中的文件,也可以使用脚本中说明的逻辑在程序中执行相同的功能。
您也可以调用脚本是这样的:
./gpuaffinity -v
,这将给稍微更详细的输出。
这里是bash脚本:
#!/bin/bash
#this script will output a listing of each GPU and it's CPU core affinity mask
file="/proc/driver/nvidia/gpus/0/information"
if [ ! -e $file ]; then
echo "Unable to locate any GPUs!"
else
gpu_num=0
file="/proc/driver/nvidia/gpus/$gpu_num/information"
if [ "-v" == "$1" ]; then echo "GPU: CPU CORE AFFINITY MASK: PCI:"; fi
while [ -e $file ]
do
line=`grep "Bus Location" $file | { read line; echo $line; }`
pcibdf=${line:14}
pcibd=${line:14:7}
file2="/sys/class/pci_bus/$pcibd/cpuaffinity"
read line2 < $file2
if [ "-v" == "$1" ]; then
echo " $gpu_num $line2 $pcibdf"
else
echo " $gpu_num $line2 "
fi
gpu_num=`expr $gpu_num + 1`
file="/proc/driver/nvidia/gpus/$gpu_num/information"
done
fi
非常感谢,这对我来说是一个很好的起点。 –
这就是所谓的设定CPU/GPU的亲和力。就我所知,以程序化的方式来做这件事并不是微不足道的。当然,您可以对系统进行手动映射,并以硬编码的方式使用它。但要自动完成,我熟悉的方法包括使用每个GPU的PCI总线ID,然后遍历系统PCI设备树以发现哪个PCIE根联合体位于同一棵树中。你正在运行Linux或Windows? [Here](http://www.ncsa.illinois.edu/UserInfo/Resources/Hardware/DellNVIDIACluster/Download/setaffinity_for_nvidia.tgz)是linux中的一个实现。 –