【发布时间】:2010-12-01 12:53:55
【问题描述】:
在CUDA C编程指南中,据说
...根据设计,主机线程在任何给定时间只能在一个设备上执行设备代码。因此,需要多个主机线程来在多个设备上执行设备代码。此外,在一个宿主线程中通过运行时创建的任何 CUDA 资源都不能被另一个宿主线程的运行时使用...
我想做的是让两个 GPU 在主机(映射内存)上共享数据,
但手册似乎说这是不可能的。
有什么解决办法吗
【问题讨论】:
标签: cuda
在CUDA C编程指南中,据说
...根据设计,主机线程在任何给定时间只能在一个设备上执行设备代码。因此,需要多个主机线程来在多个设备上执行设备代码。此外,在一个宿主线程中通过运行时创建的任何 CUDA 资源都不能被另一个宿主线程的运行时使用...
我想做的是让两个 GPU 在主机(映射内存)上共享数据,
但手册似乎说这是不可能的。
有什么解决办法吗
【问题讨论】:
标签: cuda
在分配主机内存时,应使用cudaHostAlloc() 进行分配并传递cudaHostAllocPortable 标志。这将允许多个 CUDA 上下文访问内存。
【讨论】:
解决方案是手动管理这些常用数据。即使是 SLI。
卡在 SLI 模式下实际上没有共享内存 - 共享数据必须通过总线从一个复制到另一个。
【讨论】:
您可能想查看 GMAC。它是一个建立在 CUDA 之上的库,给人一种共享内存的错觉。它实际上所做的是在主机和 GPU 设备上的相同虚拟地址上分配内存,并使用页面保护来按需传输数据。请注意,它有些实验性,可能处于 beta 测试阶段。
【讨论】:
【讨论】:
您希望通过将cudaHostAllocPortable 传递给cudaHostAlloc(),将固定内存分配为便携式。您可以肯定地在同一个固定内存的设备之间交换内核外部的数据,就像我之前做过的那样。至于映射内存,我不太确定,但我不明白为什么你不能。尝试使用cudaHostGetDevicePointer() 获取设备指针以用于当前设备(您已与同一个 CPU 线程相关联。)
CUDA 编程指南 (v3.2) 的第 3.2.5.3 节中有更多信息:
页面锁定的主机内存块可以被分配为映射和可移植的(参见第 3.2.5.1 节),在这种情况下,需要将块映射到其设备地址空间的每个主机线程都必须调用 cudaHostGetDevicePointer() 来检索设备指针,因为设备指针通常会因一个主机线程与另一个主机线程不同。
【讨论】:
我在 NVIDIA 论坛上专门问了一个类似的问题,关于如何在两个 gpu 之间传输数据,并收到回复说如果你想同时使用两个 gpu 并在它们之间传输数据,你必须有两个线程(因为手册建议)。手册说“CUDA 资源”不能共享,但是可以共享从中复制它们的主机内存(使用 openmp 或 mpi)。因此,如果您将内存从每台设备传回主机,您就可以在设备之间访问内存。
请记住,这会非常慢,因为与设备之间的内存传输会非常慢。
所以不,你不能从 gpu2 访问 gpu1 内存(即使使用 sli - 我因为与 cuda 完全没有关系而被大喊大叫)。但是您可以使用 gpu1,写入主机上的一个区域,然后使用 gpu2 并写入另一个区域,并允许管理每个设备的线程将必要的数据写回正确的 gpu。
【讨论】: