首页 > 解决方案 > OpenCL 中两个设备之间的内存传输

问题描述

我想用 OpenCL 开发一个在多 GPU 上运行的应用程序。在某些时候,应该将来自一个 GPU 的数据传输到另一个 GPU。有什么办法可以避免通过主机传输。这可以通过cudaMemcpyPeerAsync函数在 CUDA 上完成。OpenCL中是否有类似的功能?

标签: memoryopenclmulti-gpu

解决方案


在 OpenCL 中,上下文被视为内存空间。因此,如果您有多个设备与相同的上下文相关联,并且您为每个设备创建一个命令队列,则您可能会从多个设备访问相同的缓冲区对象。

当您从特定设备访问内存对象时,首先需要将内存对象迁移到该设备,以便它可以物理访问它。可以使用clEnqueueMigrateMemObjects显式完成迁移。

因此,可以像这样实现具有多个设备的简单生产者-消费者序列:

设备 1 上的命令队列:

  • 迁移内存缓冲区1
  • 将处理此缓冲区的内核排入队列
  • 保存与 buffer1 处理关联的最后一个事件

设备 2 上的命令队列:

  • 迁移内存缓冲区 1 - 使用队列 1 产生的事件来同步迁移。
  • 将处理此缓冲区的内核排入队列

我无法确定迁移到底是如何发生的,但我假设它可以是从设备 1 到设备 2 的 DMA,或者(更有可能)从设备 1 到主机,然后从主机到设备 2 的 DMA。

如果您希望避免使用单个上下文的限制或希望确保数据传输是有效的,那么您将受到供应商特定扩展的支配。

例如,AMD 提供DirectGMA技术,允许在 GPU 和任何其他 PCIe 设备(包括其他 GPU)之间进行显式远程 DMA。根据经验,它工作得非常好。


推荐阅读