我有一个装有 2 张 GTX 590 卡(4 个 GPU)的 Linux 盒子。使用 CUDA 4.0 驱动程序,我能够调用 GPU 直接内存访问并验证我的 4 个 GPU 的所有可能对之间的成功副本。
但是,在升级到 CUDA 4.1 驱动程序(或任何后续驱动程序)后,我的 GPU 直接访问对受到限制。
例如,在 CUDA 4.0 下,在以下各项之间启用了点对点:
GPU0 <-> GPU1
GPU0 <-> GPU2
GPU0 <-> GPU3
GPU1 <-> GPU2
GPU1 <-> GPU3
GPU2 <-> GPU3
但是在 CUDA 4.1(或更高版本)下,我只能访问:
GPU0 <-> GPU1(同一张卡)
GPU2 <-> GPU3(同一张卡)
GPU1 <-> GPU3
任何人都可以解释这一点或知道使用最新的 CUDA 5.x 驱动程序时的解决方法吗?
$ LSPCI -TV(有趣的部分)给出:
-[0000:00]-+-00.0 ATI Technologies Inc RD890 Northbridge only single slot PCI-e GFX Hydra part
+-02.0-[0c-0f]----00.0-[0d-0f]--+-00.0-[0f]--+-00.0 nVidia Corporation Device 1088
| | -00.1 nVidia Corporation GF110 High Definition Audio Controller
| -02.0-[0e]--+-00.0 nVidia Corporation Device 1088
| -00.1 nVidia Corporation GF110 High Definition Audio Controller
:
+-0b.0-[04-07]----00.0-[05-07]--+-00.0-[07]--+-00.0 nVidia Corporation Device 1088
| | -00.1 nVidia Corporation GF110 High Definition Audio Controller
| -02.0-[06]--+-00.0 nVidia Corporation Device 1088
| -00.1 nVidia Corporation GF110 High Definition Audio Controller
对我来说,看起来所有路径都是物理可用的(树状结构),并且在使用 cuda 4.0 时是可用的,但是当使用 cuda 4.1 及更高版本时,cudaDeviceCanAccessPeer() 为"交叉卡"通信给出 false。请注意,所有主机到设备的路径始终可用(当然)。
启用 CUDA 点对点访问由 GPU 驱动程序管理,该驱动程序检查系统配置以确定点对点访问是否可能有效。
例如,当 2 台设备之间的直接通信必须通过 QPI 链路传输时,不会启用对等访问,如此处所述。
因此,GPU 驱动程序检查系统配置,并根据系统拓扑是否可识别以及识别的拓扑是否符合某些启发式方法决定是否启用对等访问,以确定对等支持是否会成功。
在您的情况下,如果可以在同一卡上的设备之间进行通信,这仅意味着 GPU 驱动程序拓扑识别启发式方法指示当唯一的干预设备是卡上的 PCIE 交换机时,对等将成功,因此已启用(并且cudaDeviceCanAccessPeer
将返回 true)。
在您的情况下,我会说,如果您可以在同一张卡上的设备上成功启用对等访问,但不能在任何其他情况下启用,那么您的系统拓扑可能陷入某种"无法识别"的情况或可能是黑名单场景。 换句话说,这可能是预期的行为。
如果可以在同一卡上的设备之间启用对等访问,也可以在不同卡上的某些设备对之间启用对等访问,但不能在不同卡上启用其他设备对,则可能是计算机配置问题或错误。
驱动程序维护的管理启发式方法以及白名单和黑名单可能会因驱动程序版本而异,这解释了为什么在从旧版本移动到较新版本时会看到行为差异。 (是的,当您迁移到较新版本时,启发式方法可能会变得更加严格。
例如,当启发式算法最初在 CUDA 4.0 附带的 270.41.19 驱动程序中定义时,RD890 芯片组对于 PCIE P2P 被认为是"安全的"。 后来,根据测试或客户报告,可能会发现一些带有RD890的主板的化身与P2P存在某种问题。 因此,基于RD890的系统驱动程序中的P2P可能已被"关闭"。 我不知道RD890是否如此,我只是举一个例子来说明可能发生的事情,以说明为什么启发式方法会随着时间的推移变得更加严格。
我提供上述内容并不是对您的情况的完整解释,因为如果您可以在不同卡上的某些 GPU 之间启用 P2P,但不能在不同卡上的其他 GPU 之间启用 P2P,那么这对我来说听起来像是意外的行为。 我描述的其余部分只是背景信息。
您的描述对我来说并不完全清楚,因为首先您指出:
GPU0 <-> GPU1(同一张卡)
GPU2 <-> GPU3(同一张卡)
GPU1 <-> GPU3
是成功的道路。 这对我来说似乎是意想不到的行为,假设GPU1 <-> GPU3
代表"交叉卡"通信。
后来,您指出:
但是当使用 cuda 4.1 及更高版本时,cudaDeviceCanAccessPeer() 为"交叉卡"通信提供 false。
如果这是真的,则它可能只是基于驱动程序中启用启发式的修改的预期行为。
请注意,一般来说,P2P 支持可能因 GPU 或 GPU 系列而异。 能够在一种 GPU 类型或 GPU 系列上运行 P2P 并不一定表示它可以在另一种 GPU 类型或系列上运行,即使在相同的系统/设置中也是如此。 GPU P2P 支持的最终决定因素是提供的通过 cudaDeviceCanAccessPeer
查询运行时的工具。 P2P支持也可能因系统和其他因素而异。 此处所做的任何声明均不保证在任何特定设置中对任何特定 GPU 的 P2P 支持。