memory - OpenCL 中两个设备之间的内存传输
问题描述
我想用 OpenCL 开发一个在多 GPU 上运行的应用程序。在某些时候,应该将来自一个 GPU 的数据传输到另一个 GPU。有什么办法可以避免通过主机传输。这可以通过cudaMemcpyPeerAsync
函数在 CUDA 上完成。OpenCL中是否有类似的功能?
解决方案
在 OpenCL 中,上下文被视为内存空间。因此,如果您有多个设备与相同的上下文相关联,并且您为每个设备创建一个命令队列,则您可能会从多个设备访问相同的缓冲区对象。
当您从特定设备访问内存对象时,首先需要将内存对象迁移到该设备,以便它可以物理访问它。可以使用clEnqueueMigrateMemObjects显式完成迁移。
因此,可以像这样实现具有多个设备的简单生产者-消费者序列:
设备 1 上的命令队列:
- 迁移内存缓冲区1
- 将处理此缓冲区的内核排入队列
- 保存与 buffer1 处理关联的最后一个事件
设备 2 上的命令队列:
- 迁移内存缓冲区 1 - 使用队列 1 产生的事件来同步迁移。
- 将处理此缓冲区的内核排入队列
我无法确定迁移到底是如何发生的,但我假设它可以是从设备 1 到设备 2 的 DMA,或者(更有可能)从设备 1 到主机,然后从主机到设备 2 的 DMA。
如果您希望避免使用单个上下文的限制或希望确保数据传输是有效的,那么您将受到供应商特定扩展的支配。
例如,AMD 提供DirectGMA技术,允许在 GPU 和任何其他 PCIe 设备(包括其他 GPU)之间进行显式远程 DMA。根据经验,它工作得非常好。
推荐阅读
- react-testing-library - 反应测试库渲染,子道具未定义
- node.js - 不同库存用户的MongoDB数据结构
- cqrs - 如何在重启时持久化和重播 NestJS CQRS 事件和传奇?
- c++ - 在头文件中声明一个对象
- selenium-webdriver - 如何在 Mozilla 的 Selenium Web 驱动程序中使用 Java 处理弹出的网站?
- sql-server - 过滤 SQL server 查询偏移时区
- c# - 如何找出符合条件的DataGridView行数
- c - 我如何跟踪所有 fork()
- jmeter - 有没有办法在 nexus 存储库中自动存储 jmeter 结果?
- azure - 如何在 Azure 蓝图中正确使用“输出”?