【问题标题】:CUDA: CPU code in parallel to GPU codeCUDA:与 GPU 代码并行的 CPU 代码
【发布时间】:2011-06-22 09:23:20
【问题描述】:

我有一个程序,我在 GPU 上进行大量计算,然后在 CPU 上使用这些结果进行内存操作,然后如果有数据,我会获取下一批数据并从头到尾执行相同的操作。现在,如果我可以先进行第一组计算,然后在我的 CPU 处理内存操作时从第二批开始,那会快很多。我该怎么做?

【问题讨论】:

  • “内存操作” - 你的意思是数据到卡/从卡的传输,还是与卡无关的东西?你不是只需要一个线程来管理卡,然后你就可以对 CPU 的其余部分做任何你想做的事了吗?
  • 我猜都是。我将结果传输到主机,然后对数据做一些事情,所以它并不是真正独立的。

标签: cuda


【解决方案1】:

所有 CUDA 内核调用(例如function<<<blocks, threads>>>())都是异步的——它们立即将控制权返回给调用主机线程。因此,只需将 CPU 工作放在内核调用之后,您就可以始终并行执行 CPU 工作和 GPU 工作。

如果您还需要同时将数据从 GPU 传输到 CPU,则需要一个将 deviceOverlap 字段设置为 true 的 GPU(使用 cudaGetDeviceProperties() 检查),并且您需要使用 cudaMemcpyAsync()来自单独的 CUDA 流。

在 NVIDIA CUDA SDK 中有演示此功能的示例——例如“simpleStreams”和“asyncAPI”示例。

【讨论】:

  • 好的,谢谢 不知道。在这种情况下,如果我有:<<<grid,block>>myCUDAfunc(); cudaMemcpy(); 我怎么知道 myCUDAfunc() 在 cudaMemcpy 开始复制结果之前已经完成?
  • 有 cudaDeviceSynchronize、cudaStreamSynchronize 和 cudaEventSynchronize 等同步函数。这很容易使用,但您应该查看 CUDA 下载页面中来自 nVidia 的 CUDA C 编程指南。它只有 187 页,为您提供了有关使用 CUDA 的急需信息。
  • @user810045,要明确:CUDA 有“流”的概念。流是按发出顺序执行的一系列 CUDA 运行时 API 命令。如果您没有为内核指定流标识符(<<<>>> 中的可选第 4 个参数),它将在默认流中运行,该流始终与其他默认流 CUDA 命令同步。 cudaMemcpy 也是同步的,因此如果在内核之后调用它,它将始终在内核之后执行。如果你想要一个异步副本,你必须使用 cudaMemcpyAsync,它需要一个流标识符参数。
【解决方案2】:

基本思想可以是这样的:

  • 在 GPU 上进行第一批计算

  • 输入一个循环:{

    将结果从设备内存复制到主机内存

    在GPU中进行下一批计算(内核启动是异步的,控制权立即返回给CPU)

    在 CPU 上处理上一次迭代的结果

    }

  • 将上次迭代的结果从设备内存复制到主机内存

  • 上一次迭代的处理结果

您可以通过使用 cudaMemcpyAsync、cudaStream 和 cudaEvent 更好地控制 CPU 和 GPU 之间的异步工作。

正如@harrism 所说,您需要您的设备支持 deviceOverlap 以同时进行内存传输和执行内核,但即使它没有该选项,您至少可以与 CPU 上的其他计算异步执行内核。

编辑:deviceOverlap 已被弃用,应该使用 asyncEngineCount 属性。

【讨论】:

  • 是的 jmsu,这正是我想要做的。很高兴知道这会起作用:)
猜你喜欢
  • 1970-01-01
  • 2019-04-25
  • 2015-02-25
  • 2014-03-23
  • 1970-01-01
  • 2015-12-11
  • 1970-01-01
  • 2018-02-22
  • 2011-01-07
相关资源
最近更新 更多