首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当“研磨”自身时,Cuda异步MemCpy行为

当“研磨”自身时,Cuda异步MemCpy行为
EN

Stack Overflow用户
提问于 2022-07-07 22:39:28
回答 1查看 108关注 0票数 1

假设您有一个相当典型的异步计算序列:

  1. 在主机上生成数据,执行其他CPU操作。
  2. 将异步流中的数据放入设备(通过固定内存)
  3. 在(相同)异步流中计算数据

现在,如果您在循环中运行,主机将返回到步骤1,因为2和3对于主机是非阻塞的。

问题是:“如果主机再次执行第2步,而系统还没有完成向设备传输数据,那么主机会发生什么情况?”

  • 主机MemCpyAsync在上一份副本完成之前会阻塞吗?
  • 当将出站数据放入缓冲区时,它会像平常一样启动吗?

如果是后者,假设如果主机运行得太快,这个缓冲区可能会耗尽空间,wrt设备操作吗?

我知道现代设备有多个复制引擎,但我不确定这些引擎对同一流上的多个副本是否有用,对同一个地方是否有用。

我明白,一个遇到这种情况的系统不会是一个设计良好的系统--把询问作为一个知识点。

这不是我在代码中遇到的东西--寻找关于这种行为应该如何工作的文档的任何指针。已经查看了复制函数和异步行为的API页面,没有看到任何我能够识别的相关内容。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-07 23:08:49

主机MemCpyAsync在上一份副本完成之前会阻塞吗?

不,通常不是,假设“块”是指阻塞CPU线程。发出给GPU的异步工作项进入队列,控制在工作开始之前立即返回到CPU线程。队列可以容纳“许多”项目。工作的发布可以一直进行,直到队列已满,而没有任何其他障碍或依赖。

记住语义的两个规则之一是很重要的:

  • 在同一流中发出的项按发出顺序执行。B项,在A项之后印发,直到A项完成后才开始。

因此,假设有这样的情况(假设h_ibuffh_obuff指向固定的主机内存):

代码语言:javascript
运行
复制
cudaStream_t stream;
cudaStreamCreate(&stream);
for (int i = 0; i < frames; i++){
  cudaMemcpyAsync(d_ibuff, h_ibuff, cudaMemcpyHostToDevice, stream);
  kernel<<<...,stream>>>(...);
  cudaMemcpyAsync(h_obuff, d_obuff, cudaMemcpyDeviceToHost, stream);
  }

在循环的第二次传递中,cudaMemcpyAsync操作将被插入到队列中,但在流语义表明它们可以开始之前,不会开始执行(或执行任何事情)。这个循环发出的每一个op都是这样的。

一个合理的问题可能是“如果在循环的每一次传递中,我都希望h_ibuff中有不同的内容呢?”(相当明智)。那么你就需要具体地解决这个问题。例如,插入一个简单的memcpy操作来“重新加载”h_ibuff是行不通的。你需要某种同步。例如,当内核和后续的h_ibuff D->H操作发生时,您可能会决定要“重新填充”cudaMemcpyAsync。你可以这样做:

代码语言:javascript
运行
复制
cudaStream_t stream;
cudaEvent_t event;
cudaEventCreat(&event);
cudaStreamCreate(&stream);
for (int i = 0; i < frames; i++){
  cudaMemcpyAsync(d_ibuff, h_ibuff, cudaMemcpyHostToDevice, stream);
  cudaEventRecord(event, stream);
  kernel<<<...,stream>>>(...);
  cudaMemcpyAsync(h_obuff, d_obuff, cudaMemcpyDeviceToHost, stream);
  cudaEventSynchronize(event);
  memcpy(h_ibuff, databuff+i*chunksize, chunksize); // "refill"
  }

这种重构将允许发出异步工作,以保持GPU的忙碌,并将副本“重叠”为“填充”h_ibuff。它还将防止“填充”操作从开始到以前的缓冲区内容安全地传输到设备,还将防止下一个缓冲区副本从开始一直到新内容被“重新加载”。

这不是唯一的方法;这是一种可能的方法。

对于上面问/回答的最后一个问题,您可能会问一个类似的问题:“如何处理输出缓冲区端?”这一机制可能非常相似,留给读者。

关于这个主题的结构化学习,您可能希望学习本讲座系列的CUDA并发部分。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72904943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档